skynet 是单进程多线程框架,每个 lua service 独立运行在自己的 lua vm 里,而本篇文章要实现的是让一个 service 发送消息,另一个 service 处理消息。
一、skynet 启动新 service
local skynet = require "skynet"
skynet.start(function()
skynet.newservice("myservice/msg_dispatcher")
skynet.newservice("myservice/worker")
skynet.exit()
end)
启动 myservice 目录下的两个服务:msg_dispatcher 与 worker。
二、发送消息
每隔 1 s,向 worker 服务发送一条消息:
local skynet = require "skynet"
function sendmsg()
skynet.send("worker", "lua", "say", "Hello world!")
skynet.timeout(100, sendmsg)
end
skynet.start(function()
skynet.timeout(100, sendmsg)
end)
- function skynet.timeout(time, func):定时器,time:超时时间(单位是 1/100 秒);func:超时回调函数。
- function skynet.send(addr, type, …):addr:服务的地址,可以是服务的32位整数识别 id 或字符串别名(别名需要该服务自行注册才能使用);type:消息类型,常用 lua 表示;…:变长参数,一般约定第一个是命令类型,再往后是命令参数。
三、接收消息
使用 skynet.dispatch(),对指定类型的消息进行处理:
local skynet = require "skynet"
require "skynet.manager"
local CMD = {}
CMD.say = function (text)
print(text)
end
skynet.start(function()
skynet.register("worker")
skynet.dispatch("lua", function(session, source, cmd, ...)
print("[worker] received `"..cmd.."`")
local f = CMD[cmd]
f(...)
end)
end)
- register(name):给当前服务注册一个别名;
- dispatch(type, func):为 type 类型的消息指定处理函数 func。回调函数形式如:function (session, source, …),其中:
- session:确保能将消息处理结果对应到某条消息,如服务器收到两条请求,其中一条处理完毕后,处理结果会作为该请求的响应返回;
- source:消息的来源,整数id;
- cmd:例子中的 cmd 参数其实也属于变长参数的一部分,但一般约定变长参数的第一个参数是服务要执行的命令,因此就给了个 cmd 的名字。
四、结果