Skynet作为一个服务端最核心的功能自然是消息传递,还记得刚学Erlang也是写了一个PingPong程序,今天来看看Skynet如何完成
首先来看功能描述,需要做一个什么功能
功能描述
如图所示,开启两个ping节点ping1、ping2,让ping1给ping2发消息,ping2收到后回应ping1,ping1收到后再回应ping2,不断循环。
程序
接着我们上节的 skynet下载、编译、运行 里面的结构开发
首先新建examples/Pmain.lua
Pmain.lua
local skynet = require "skynet"
skynet.start(function()
skynet.error("[Pmain] start")
local ping1 = skynet.newservice("ping")
local ping2 = skynet.newservice("ping")
skynet.send(ping1, "lua", "start", ping2)
skynet.exit()
end)
可以看到代码首先会打印"[Pmain] start",然后开启了两个ping类型的服务,地址分别为ping1、ping2,最后调用skynet.send,主程序向ping1发送名为"start"的消息,最后带了一个参数为ping2,然后主程序就退出了
我们在Skynet中启动需要配置文件,在examples中新建配置文件Pconfig,主要是修改start入口
Pconfig
--必须配置
thread = 8 --启用多少个工作线程
cpath = "./cservice/?.so" --用C编写的服务模块的位置
bootstrap = "snlua bootstrap" --(固定)启动的第一个服务
--bootstrap配置项
start = "Pmain" --主服务入口
harbor = 0 --(固定)不使用主从节点模式
--lua配置项(暂时固定)
lualoader = "./lualib/loader.lua"
luaservice = "./service/?.lua;".."./test/?.lua;".."./examples/?.lua;".."./test/?/init.lua"
lua_path = "./lualib/?.lua;" .. "./lualib/?/init.lua"
lua_cpath = "./luaclib/?.so"
--后台模式(必要时开启)
--daemon = "./skynet.pid"
--logger = "./userlog"
然后我们来编写ping服务的代码
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)
注意start初始化函数中,调用skynet.dispatch,指定lua类型消息的处理方法,收到消息后,查找CMD[cmd]这个方法是否存在,存在就调用他,比如ping1收到主服务的“start”消息,则会调用CMD.start(source,…),source表示消息来源(这里是主服务)
此外ping服务除了接收主服务的消息,还可以接收其他ping服务发来的消息
查看CMD.ping和CMD.start可以发现就是让ping1和ping2互相发送消息,且传递的参数递增1,我们运行一下看看
发现确实如我们所愿