作者:shihuaping0918@163.com,轉(zhuǎn)載請注明作者
自從skynet源碼分析系列文章發(fā)布以后,陸續(xù)收到不少的反饋,說需要一個step by step的教程,身邊的朋友也要求出個教程。?于是就寫了這個教程。
每個教程都是從hello world開始的,所以先寫一個echo服務(wù)作為hello world版本。echo服務(wù)先放在skynet/example這個目錄下,因?yàn)榕渲孟嚓P(guān)的東西還沒有講到。環(huán)境準(zhǔn)備需要:
1.inux或者mac osx。
2.編繹好的skynet。
3.一個可以編寫lua的編輯器??蓞⒖嫉氖莈clipse ldt/sublime text
skynet的WIKI是需要熟讀的,wiki的篇幅很大,但是不讀WIKI對于開發(fā)很不利。
https://github.com/cloudwu/skynet/wiki
skynet剛開始是單進(jìn)程多線程的,它是由一個一個的服務(wù)組成的。在skynet上做開發(fā),實(shí)際上就是在寫服務(wù)。服務(wù)與服務(wù)之間通過消息隊(duì)列進(jìn)行通信。這一篇講的就是服務(wù)該怎么寫。
一、首先引入框架
local skynet = require "skynet"
然后要準(zhǔn)備一個回調(diào)函數(shù),每個服務(wù)都有一個回調(diào)函數(shù),這個回調(diào)函數(shù)是被skynet框架調(diào)用的,當(dāng)有消息投遞到服務(wù)上時,skynet框架就會調(diào)用服務(wù)的回調(diào)函數(shù)對消息進(jìn)行處理。這個回調(diào)函數(shù)是skynet.dispatch。
最后要使用skynet.start把服務(wù)啟動起來。
skyet/example/echo.lua
local skynet = require "skynet"
require "skynet.manager"
local command = {}
function command.HELLO(what)
return "i am echo server, get this:" .. what
end
function dispatcher()
skynet.dispatch("lua", function(session, address, cmd, ...)
cmd = cmd:upper()
if cmd == "HELLO" then
local f = command[cmd]
assert(f)
skynet.ret(skynet.pack(f(...)))
end
end)
skynet.register("echo")
end
skynet.start(dispatcher)
這里需要解釋一下,session,address,cmd是什么,...是代表可變參數(shù),這個就不解釋了。session在代碼分析的時候講過,它是一個自增的數(shù)字,而且溢出了又從1開始。實(shí)際上可以理解為請求序號,請求方收到回應(yīng)的時候,用session這個數(shù)字就能識別出來回應(yīng)包是對應(yīng)的哪一個發(fā)出去的請求,這個請求是請求方發(fā)出去的。在異步請求的時候經(jīng)常需要這個東西。
address是skynet中服務(wù)的地址,這個地址在運(yùn)行時是唯一的。在上面的代碼中就是代表echo服務(wù)自已的地址。它實(shí)際上也是一個數(shù)字。
cmd就是命令字了,這個就不多解釋了。下面還會講到。
skynet.register("echo")這一句就是給服務(wù)起個名字,這個在源碼分析的時候也講過了,這個名字是不可以重復(fù)的。
二、寫完上面的代碼是不是就大功告成了呢,實(shí)際上并沒有。要測這個服務(wù),我們還需要另寫一個服務(wù),可能有的人心中默默地已經(jīng)在念三字經(jīng)了。在沒有搭建服務(wù)端,純在skynet環(huán)境中運(yùn)行測試,目前只能這樣了。
skynet/example/test_echo.lua
local skynet = require "skynet"
skynet.start(function()
local echo = skynet.newservice("echo")
print(skynet.call(echo, "lua", "HELLO", "world"))
end);
注意不要直接使用skynet去啟動test_echo.lua腳本,一定會報(bào)錯的。不管我這里怎么講,我相信一定會有人要去試一試的。
skynet.newservice是啟動echo服務(wù)。
skynet.call是調(diào)用服務(wù),其中參數(shù)echo就是上面dispatch對應(yīng)的address,參數(shù)"lua"就是dispatch中的lua,"HELLO"就是上面對應(yīng)的cmd。參數(shù)"world"就是...里面的內(nèi)容了。call是阻塞式調(diào)用。
到了這一步是不是就可以了?不不不,還有第三步,不過第三步很簡單。
三、修改配置文件example/config
在源碼分析中分析過了,skynet一定需要一個配置文件,在里面配置cpath/thread之類的信息。先備份一下example/config文件。然后再個性example/config文件,把start那一行
start = "main" -- main script
改為
start = "test_echo" -- main script
保存,保存,保存,重要的事情說三遍,一定要保存。
這個start就是skynet要去運(yùn)行的lua入口腳本
四、好了,現(xiàn)在運(yùn)行
./skynet ./example/config,恭喜你,成功的話會出現(xiàn)
i am echo server, get this:world
[:01000002] KILL self
到此為止,服務(wù)的編寫例子就完成了。這一篇里我們學(xué)習(xí)了skynet.start、skynet.dispatch、skynet.register、skynet.call、skynet.newservice這幾個重要的方法。順便看了一下配置文件。