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 的名字。
四、結果