美文网首页
Skynet基础教程02.service基础操作

Skynet基础教程02.service基础操作

作者: JasminePowered | 来源:发表于2017-03-26 12:28 被阅读0次

    本篇主要内容

    • lua service的基础操作
    • 介绍其中可能会遇到的坑

    需要前提了解的知识

    • Skynet的基本启动

    lua service基础操作

    创建与销毁

    projects/hello_world中,我们在配置文件指定了主入口服务,类似main函数,一般会通过它来启动其他的service。接下来我们来分析下它的代码:

    local Skynet = require "skynet"
    local Log = require "log"
    
    local function __init__()
        Skynet.newservice('debug_console', Skynet.getenv("CONSOLE_PORT"))
        Skynet.newservice('hello_world')
        Skynet.exit()
    end
    
    Skynet.start(__init__)
    
    • 第1行 skynet的模块是整个框架主要的LuaApi库,绝大部分lua的接口都来源于此。

    • 最后一行,通过Skynet.start可以注册service的初始化函数

    • init函数中,使用了Skynet.newservice创建了两个service对象。

      第一个参数代表服务类名(相当于面向对象中的class), 后面是参数列表

      虽然还有其他的创建service的函数,推荐使用newservice。

    • init函数的最后,调用了Skynet.exit关闭该service。如果需要创建的service常驻,最后不调用exit函数即可。

    • 如果想要让一个service关闭另一个service怎么做呢?可以用Skynet.kill,不过需要先拿到目标service的地址,比如下面的例子:

    print("my_addr:", Skynet.self()) -- 获取自己地址
    local obj = Skynet.newservice("hello_world") -- 创建并把地址记录下来
    Skynet.kill(obj) -- 杀掉目标
    

    消息发送与分发

    • 调用方式有两种,分别是SEND和CALL。SEND表示不等待调用返回,是非阻塞式的;CALL表示会等待返回,是阻塞式的

      可以用Skynet.send和Skynet.call发送消息,对应上面的例子,大概是这样:

    Skynet.send(addr, "lua", "test_send", "hello jasmine")
    Skynet.call(addr, "lua", "test_call", 1, 2)
    
    • 接收方可以使用Skynet.dispatch注册分发函数,一般写在service的启动逻辑中

      比如下面这个例子,表示注册了lua协议消息,其中test_send和test_call是消息名:

    local CMD = {}
    function CMD.test_send(s)
        print("test_send:", s)
    end
    
    function CMD.test_call(a, b)
        print("test_call:", a, b)
        Skynet.retpack({code = 200, sum = a + b})
    end
    
    Skynet.dispatch("lua", function(session, source, cmd, ...)
        local f = assert(CMD[cmd])
        f(...)
    end)
    
    • 仔细一些同学可能会发现发送和分发都需要写一个"lua"

      这个是表示消息的类型,目前默认的已经有十几种,开发者也可以根据需要自定义类型,可以使用下面的接口注册,然后发送方把"lua"改成相应的协议名就可以了:

    -- 发送者和接收者都需要注册
    skynet.register_protocol {
      name = "text", # 协议名称
      id = skynet.PTYPE_TEXT, # 协议ID
      pack = function(m) return tostring(m) end, # 消息编码
      unpack = skynet.tostring, # 消息解码
    }
    

    需要注意的地方

    • Skynet.newservice时的传参,目前都是string类型,比如传了数字,需要自行转换

    练习题

    • 阅读并运行练习题仓库中projects/service_rpc的代码,在start服务中增加一段直接杀掉新建的test_rpc服务的逻辑,在test_rpc服务中增加一个关闭服务的接口
    • 定义一种新的协议类型(类似text和lua),然后尝试写几个相关的接口

    参考资料

    官方Wiki LuaApi
    练习题仓库

    相关文章

      网友评论

          本文标题:Skynet基础教程02.service基础操作

          本文链接:https://www.haomeiwen.com/subject/myysgttx.html