官术网_书友最值得收藏!

2.4 寫Echo,練習(xí)網(wǎng)絡(luò)編程

游戲服務(wù)端要處理客戶端請求,作為服務(wù)端引擎,網(wǎng)絡(luò)編程也是Skynet的核心功能。

2.4.1 功能需求

圖2-14是開啟處理客戶端消息的服務(wù),它會把收到的內(nèi)容原封不動地發(fā)回給客戶端。

圖2-14 Echo程序示意圖

2.4.2 學(xué)習(xí)網(wǎng)絡(luò)模塊

skynet.socket模塊提供了網(wǎng)絡(luò)編程的API,Echo程序會用到它們,如表2-6所示。

表2-6 處理網(wǎng)絡(luò)消息的API

更多API參見https://github.com/cloudwu/skynet/wiki/Socket,本節(jié)暫不列舉太多,后面用到時再做介紹。socket.read中所謂的阻塞模式和skynet.call一樣,都利用了Lua的協(xié)程機制。調(diào)用socket.read,服務(wù)有可能被掛起,直到接收到數(shù)據(jù),才會往下執(zhí)行。2.9節(jié)將對阻塞模式做進一步說明。

2.4.3 代碼實現(xiàn)

本例只需開啟一個服務(wù)。修改主服務(wù)Pmain,程序結(jié)構(gòu)如代碼2-5所示。先引入skynet和skynet.socket這兩個模塊,在服務(wù)啟動后(使用skynet.start的回調(diào)方法),依次調(diào)用socket.listen和socket.start來監(jiān)聽8888端口。socket.start的回調(diào)方法connect見代碼2-6。

代碼2-5 examples/Pmain.lua

(資源:Chapter2/3_echo.lua)


local skynet = require "skynet"
local socket = require "skynet.socket"
    
skynet.start(function()
    local listenfd = socket.listen("0.0.0.0", 8888)
    socket.start(listenfd ,connect)
end)

新客戶端發(fā)起連接時,connect方法將被調(diào)用。在while循環(huán)里,程序先用socket.read接收數(shù)據(jù),如果收到數(shù)據(jù)(if readdata~=nil的真分支),則通過socket.write將數(shù)據(jù)發(fā)回客戶端;如果客戶端斷開了連接(if readdata~=nil的假分支),則調(diào)用socket.close關(guān)閉連接。代碼中的print方法用于打印調(diào)試信息,與skynet.error類似。

代碼2-6 examples/Pmain.lua


function connect(fd, addr)
    --啟用連接
    print(fd.." connected addr:"..addr)
    socket.start(fd)
    --消息處理
    while true do
        local readdata = socket.read(fd)
        --正常接收
        if readdata ~= nil then
            print(fd.." recv "..readdata)
            socket.write(fd, readdata)
        --斷開連接
        else
            print(fd.." close ")
            socket.close(fd)
        end
    end
end

2.4.4 運行結(jié)果

執(zhí)行./skynet examples/Pconfig運行服務(wù)端程序。

說明:如果開啟服務(wù)端時提示“init service failed: ./lualib/skynet/socket.lua:360: Listen error”,意味著監(jiān)聽端口8888被占用,可能是多次運行服務(wù)端所致,可以(在測試環(huán)境下)執(zhí)行“killall-9 skynet”關(guān)閉所有的Skynet進程。

再啟動客戶端程序(如telnet),連接服務(wù)端。

知識拓展:telnet是Linux下的一個程序,可用于調(diào)試TCP連接。如果尚未安裝,可在CentOS下執(zhí)行“yum install telnet”安裝。輸入“telnet [ip] [端口]”即可向指定服務(wù)器發(fā)起連接(圖2-15所示為連接127.0.0.1:8888),還可以在telnet中輸入內(nèi)容,按回車鍵可將字符串發(fā)給服務(wù)端。

如果使用云服務(wù)器時能夠在本機上調(diào)試,但無法跨機器連接,很可能是云服務(wù)器防火墻屏蔽了客戶端連接,可以設(shè)置云服務(wù)器的“安全策略”以開放端口。

Echo程序的運行結(jié)果如圖2-16所示,這里先后開啟了兩個客戶端,分別輸入“l(fā)py”和“helloskynet”,服務(wù)端將會給出回應(yīng)。圖中客戶端部分白色字體代表用戶輸入,灰色字體代表程序輸出,灰色箭頭代表消息的流向。

圖2-15 向指定服務(wù)器發(fā)起連接

圖2-16 Echo程序的運行結(jié)果

主站蜘蛛池模板: 张家港市| 仙游县| 泾川县| 内乡县| 石门县| 陇西县| 巨鹿县| 中卫市| 福泉市| 聊城市| 新干县| 西平县| 砀山县| 濉溪县| 绥德县| 黎平县| 镇雄县| 林西县| 满城县| 宣化县| 平谷区| 安多县| 宜兰市| 林甸县| 云龙县| 馆陶县| 清丰县| 武胜县| 邳州市| 荔浦县| 延川县| 翼城县| 阳西县| 阳高县| 凉山| 南汇区| 富阳市| 雷州市| 镇康县| 碌曲县| 万荣县|