- 百萬在線:大型游戲服務(wù)端開發(fā)
- 羅培羽
- 906字
- 2021-09-17 17:04:56
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é)果
- Mastering NetBeans
- Cocos2D-X權(quán)威指南(第2版)
- JavaScript+DHTML語法與范例詳解詞典
- 摩登創(chuàng)客:與智能手機和平板電腦共舞
- 自然語言處理Python進階
- Python Data Structures and Algorithms
- C++從入門到精通(第6版)
- 零基礎(chǔ)學(xué)C語言(升級版)
- Java EE Web應(yīng)用開發(fā)基礎(chǔ)
- Drupal 8 Development:Beginner's Guide(Second Edition)
- The Statistics and Calculus with Python Workshop
- 企業(yè)級Java現(xiàn)代化:寫給開發(fā)者的云原生簡明指南
- 讓Python遇上Office:從編程入門到自動化辦公實踐
- Android項目實戰(zhàn):博學(xué)谷
- Scala編程(第4版)