【从零开始学Skynet】基础篇(三):服务模块常用API

1、服务模块       

          Skynet提供了开启服务和发送消息的API,必须要先掌握它们。列出了Skynet中8个最重要的API,PingPong程序会用到它们。

Lua API说明
newservice(name, ...)

启动一个名为 name 的新服务,并返回服务的地址。

start(func)        用 func 函数初始化服务,并将消息处理函数注册到 C 层,让该服务可以工作。
dispatch(type, func) 

        为 type 类型的消息设定一个处理函数。Skynet支持多种消息类型,由于Lua服务间的消息类型是“lua”,因此这里暂时将它定为“lua”。func是指收到消息后的处理函数,当一个服务收到消息时,skynet就会开启新协程,并调用它。       

send(addr, type, ...)

        用 type 类型向 addr 发送一个消息,消息名为cmd。发送方用skynet.send发送消息,接收方用skynet.dispatch接受消息,它们的参数相互对应。若用于服务间通信,类型一般固定为“lua”

call(addr, type, ...)用 type 类型发送一个消息到 addr ,并等待对方的回应。skynet.call是个阻塞方法。
exit()

结束当前服务。

self()返回当前服务的地址。
error(msg)打印日志,向 log 服务发送一条消息。

更多API可以参见:https://github.com/cloudwu/skynet/wiki/APIList

 2、程序开发 

        初看API文档可能一头雾水,结合下面的实例开发才能融会贯通。

        按如下图所示,开启两个ping类型的服务ping1和ping2,让ping1给ping2发消息,ping2收到

后回应ping1,ping1收到再回应ping2,不断循环。

3、代码实现 

(1)主服务

           在skynet/examples目录下新建main_ping.lua文件,输入如下所示代码:

local skynet = require "skynet"
skynet.start(function()
    skynet.error("[PingMain] start")
    local ping1 = skynet.newservice("Ping")
    local ping2 = skynet.newservice("Ping")

    skynet.send(ping1, "lua", "start", ping2)
    skynet.exit()
end)
  1. 主服务启动服务后,会先打印“[PingMain]start”的日志输出;
  2. 然后开启两个 ping 类型的服务,它们的地址分别存为ping1 ping2
  3. 再调用 skynet.send ,让主服务向 ping1 发送名 为“start” 的消息(图中的阶段 ),附带一个参数 ping2
  4. 最后,主服务完成使命,退出

(2)ping服务

         在skynet/examples目录下新建ping.lua文件,输入如下所示代码:

local skynet = require "skynet"

local CMD = {}

function CMD.start(source, target)
    skynet.send(target, "lua", "ping", 1)
end

function CMD.ping(source, count)
    local id = skynet.self()
    skynet.error("["..id.."] recv ping count="..count)
    skynet.sleep(100)
    skynet.send(source, "lua", "ping", count+1)
end

skynet.start(function()
    skynet.dispatch("lua", function(session, source, cmd, ...)
      local f = assert(CMD[cmd])
      f(source,...)
    end)
end)
    为使代码简洁,两个回调方法都使用了匿名函数。代码说明:
  1. 先用skynet.start初始化服务;
  2. 然后在回调方法中调用skynet.dispatch,指定lua类型消息的处理方法,参数session代表消息的唯一id,可暂时先不管。source代表消息来源,指发送消息的服务地址,cmd代表消息名,“...”是一个可变参数,内容由发送方的skynet.sendskynet.call指定。       
  3. 收到其他服务的消息后,查找CMD[cmd]这个方法是否存 在,如果存在就调用它;
  4. ping1服务收到主服务的“start”消息时,程序会调用CMD.start(source, ...)。其中,参数source代表消息来源,其他参数由发送方传送。
  5. ping服务可以接收两种消息:一种是主服务发来的start消息;另一种是其他ping服务发来的ping消息。
        主服务会在启动两个ping 服务后给 ping1 发送 start 消息,语句 是“skynet.send(ping1, "lua", "start", ping2) ,最后一个参数对应CMD.start的参数 target ,代表要让 ping1 发消息给谁。 ping1 收到后,会给ping2 发送一条 ping 消息,附带参数 “1” ping2 收到后,执行CMD.ping,参数 “1” 对应参数 count ping2 也会给 ping1 (发送方 source)发送 ping ,并把记数值 count 1 ,如此往复。

(3)配置文件

        在 skynet/examples目录下新建 PingConfig文件,然后把config中的内容复制过来稍加修改,内容如下所示:
include "config.path"

thread = 8
logger = nil
logpath = "."
harbor = 0
start = "main_ping"	-- main script
bootstrap = "snlua bootstrap"	-- The service for bootstrap
-- snax_interface_g = "snax_g"
cpath = root.."cservice/?.so"
-- daemon = "./skynet.pid"

(4)运行结果

        最后打开终端,输入如下指令,显示运行结果。

        其中0000000a10 代表 ping2 的地址(一个十六进制一个十进制,它们是相同的值,根据不
同配置,读者看到的数值可能不同),00000009 9 代表 ping1 的地址。 ping2 先打印出计数值 1
接着 ping1打印出计数值 2 ,然后 ping2 再打印出计数值 3 ,以此类推。
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值