作者:shihuaping0918@163.com蓄髓,轉(zhuǎn)載請(qǐng)注明作者
按照skynet的慣例锡足,網(wǎng)絡(luò)服務(wù)器一般是用gate/watchdog/agent三劍客别洪。這個(gè)例子也不例外飘弧,因?yàn)閟kynet底層的socket不能算是非常的易用榄笙。
服務(wù)端與node.js的客戶端之間使用json傳輸數(shù)據(jù)邪狞。
目錄結(jié)構(gòu)仍然像第2篇中的一樣,項(xiàng)目根目錄為skynet_howto办斑。
搭建基本的網(wǎng)絡(luò)功能:
main.lua 管理服務(wù)外恕,啟動(dòng)服務(wù)。
agent.lua agent服務(wù)乡翅,負(fù)責(zé)請(qǐng)求路由鳞疲。
watchdog.lua 看門狗,負(fù)責(zé)啟動(dòng)agent蠕蚜。
可能有的人疑問(wèn)尚洽,為什么沒有g(shù)ate.lua?gate服務(wù)已經(jīng)被標(biāo)準(zhǔn)化了,放在skynet框架里了靶累。所以不需要自己寫gate.lua腺毫,直接拿來(lái)用就好了。
那么gate/agent/watchdog三者的關(guān)系是什么挣柬?還是從網(wǎng)絡(luò)請(qǐng)求的處理過(guò)程來(lái)講比較直觀潮酒,首先一個(gè)連接進(jìn)來(lái),先到gate邪蛔,gate會(huì)給watchdog發(fā)一個(gè)請(qǐng)求急黎。watchdog就會(huì)啟動(dòng)一個(gè)agent。agent啟動(dòng)以后會(huì)給gate發(fā)個(gè)請(qǐng)求forward,gate就會(huì)給連接加上agent屬性勃教。當(dāng)這個(gè)連接再有數(shù)據(jù)進(jìn)來(lái)的時(shí)候淤击,還是經(jīng)過(guò)gate,但是gate檢查到這個(gè)連接已經(jīng)有agent屬性以后故源,數(shù)據(jù)就直接發(fā)給agent了污抬,不會(huì)再發(fā)給watchdog。
用一個(gè)簡(jiǎn)單的圖形表示就如下绳军。
client -> gate -> watchdog -> agent
client->gate->agent
搞清楚了這個(gè)過(guò)程以后印机,去看一下skynet/example下的watchdog.lua和agent.lua就很容易了∩玖澹可以簡(jiǎn)單地理解為watchdog實(shí)際上只有建立連接的時(shí)候有用耳贬,連接建立時(shí)它啟動(dòng)了一個(gè)agent。在agent沒啟動(dòng)好的時(shí)候猎唁,連接上過(guò)來(lái)的所有數(shù)據(jù)都發(fā)到watchdog咒劲,watchdog把數(shù)據(jù)直接扔掉。當(dāng)agent啟動(dòng)好以后诫隅,gate的數(shù)據(jù)就不再經(jīng)過(guò)watchdog腐魂,直發(fā)agent。
講原理講了很大的篇幅了逐纬,下面來(lái)寫代碼蛔屹。watchdog.lua不需要更改,直接把skynet/example/watchdog.lua拷過(guò)來(lái)就好了豁生。要改的就要是agent.lua兔毒。
agent.lua v1
local skynet = require "skynet"
local socket = require "skynet.socket"
local WATCHDOG
local host
local send_request
local CMD = {}
local REQUEST = {}
local client_fd
function CMD.start(conf)
local fd = conf.client
local gate = conf.gate
WATCHDOG = conf.watchdog
-- slot 1,2 set at main.lua
skynet.fork(function()
while true do
socket.write(client_fd, "heartbeat")
skynet.sleep(500)
end
end)
client_fd = fd
skynet.call(gate, "lua", "forward", fd)
end
function CMD.disconnect()
-- todo: do something before exit
skynet.exit()
end
skynet.start(function()
skynet.dispatch("lua", function(_,_, command, ...)
local f = CMD[command]
skynet.ret(skynet.pack(f(...)))
end)
end)
這個(gè)版本的agent.lua只實(shí)現(xiàn)了最基本的網(wǎng)絡(luò)功能,還有發(fā)心跳包的功能甸箱。
然后還需要一個(gè)main.lua
main.lua
local skynet = require "skynet"
local max_client = 64
skynet.start(function()
skynet.error("Server start")
if not skynet.getenv "daemon" then
local console = skynet.newservice("console")
end
skynet.newservice("debug_console",8000)
skynet.newservice("echo")
local watchdog = skynet.newservice("watchdog")
skynet.call(watchdog, "lua", "start", {
port = 8888,
maxclient = max_client,
nodelay = true,
})
skynet.error("Watchdog listen on", 8888)
skynet.exit()
end)
最后把config/config文件里的start改為main育叁,然后運(yùn)行。一切正常的話芍殖,就可以用telnet試一下能不能連上了豪嗽。
telnet 127.0.0.1 8888
下一篇要講的是protobuf在skynet中怎么使用。
如果覺得這篇文章對(duì)您有所幫助豌骏,請(qǐng)點(diǎn)贊或者賞杯咖啡吧龟梦。