- 百萬在線:大型游戲服務端開發
- 羅培羽
- 1271字
- 2021-09-17 17:04:55
2.3 第一個程序PingPong
服務向另一個服務發送消息,是Skynet的最核心功能。PingPong是個很簡單的程序,下面用它來學習如何開啟服務、如何發送消息。
2.3.1 功能需求
如圖2-10所示,開啟兩個ping類型的服務ping1和ping2,讓ping1給ping2發消息,ping2收到后回應ping1,ping1收到再回應ping2,不斷循環。PingPong與1.7.2節的Actor程序“相互督促工作,努力賺錢”很相似。

圖2-10 PingPong程序示意圖
2.3.2 學習服務模塊
Skynet提供了開啟服務和發送消息的API,必先掌握它們。表2-5列出了Skynet中8個最重要的API,PingPong程序會用到它們。更多API可以參見https://github.com/cloudwu/skynet/wiki/APIList,此處暫不列舉太多,用到時再做介紹。
表2-5 Skynet中8個最重要的API



圖2-11 skynet.call的示意圖
2.3.3 代碼實現
初看API文檔可能一頭霧水,結合代碼才能融會貫通。按照2.3.1節的需求,PingPong程序必須包含主服務和ping服務。
1.主服務
新建文件examples/Pmain.lua,主服務如代碼2-2所示。
代碼2-2 examples/Pmain.lua中的主服務代碼
(資源:Chapter2/2_pingpong_main.lua)
local skynet = require "skynet" skynet.start(function() skynet.error("[Pmain] start") local ping1 = skynet.newservice("ping") local ping2 = skynet.newservice("ping") skynet.send(ping1, "lua", "start", ping2) skynet.exit() end)
說明:可以用Vim等工具直接在Linux上編輯文檔,也可以使用WinSCP、Samba等工具在Windows上編輯。
圖2-12是代碼2-2的示意圖,主服務啟動服務后,會先打印“[Pmain]start”(沒特別的作用,用于驗證程序是否運行到skynet.start的回調函數了),然后開啟兩個ping類型的服務,它們的地址分別存為ping1和ping2。再調用skynet.send,讓主服務向ping1發送名為“start”的消息(圖中的階段①),附帶一個參數ping2。最后,主服務完成使命,退出。

圖2-12 代碼2-2的示意圖
為使Skynet啟動Pmain,需設置配置文件。在examples中新建配置文件Pconfig,可以復制原先的Config文件,并將其中的start="main"改為start="Pmain"。Skynet會找到Pmian.lua作為主服務。也可以復制2.2.2節的配置模板,同樣,設置主服務為Pmain。
2.ping服務
新建文件examples/ping.lua,編寫ping服務。Skynet服務的基礎結構如代碼2-3所示(主服務功能單一,因此使用更簡單的寫法)。
代碼2-3 examples/ping.lua中的ping服務代碼
(資源:Chapter2/2_pingpong_ping.lua)
local skynet = require "skynet" local CMD = {} skynet.start(function() skynet.dispatch("lua", function(session, source, cmd, ...)end) end)
在代碼2-3中,先用skynet.start初始化服務,然后在回調方法中調用skynet.dispatch,指定lua類型消息的處理方法。為使代碼簡潔,兩個回調方法都使用了匿名函數。代碼中帶底紋的兩句值得重點關注,其含義是:收到其他服務的消息后,查找CMD[cmd]這個方法是否存在,如果存在就調用它。例如,當ping1服務收到主服務的“start”消息時,程序會調用CMD.start(source, ...)。其中,參數source代表消息來源,其他參數由發送方傳送。
ping服務可以接收兩種消息:一種是主服務發來的start消息;另一種是其他ping服務發來的ping消息。如代碼2-4展示了這兩種消息的處理方法。
代碼2-4 examples/ping.lua中的ping服務消息處理
function CMD.start(source, target) skynet.send(target, "lua", "ping", 1) end function CMD.ping(source, count) local id = skynet.self() skynet.error("["..id.."] recv ping count="..count) skynet.sleep(100) skynet.send(source, "lua", "ping", count+1) end
主服務會在啟動兩個ping服務后給ping1發送start消息,語句是“skynet.send(ping1, "lua", "start", ping2)”,最后一個參數對應CMD.start的參數target,代表要讓ping1發消息給誰。ping1收到后,會給ping2發送一條ping消息,附帶參數“1”。ping2收到后,執行CMD.ping,參數“1”對應參數count。ping2也會給ping1(發送方source)發送ping,并把記數值count加1,如此往復。
代碼中的skynet.sleep(100)指讓協程(ping方法)暫停1秒,這僅僅為了降低程序運行速度,讓讀者可以看清日志。
2.3.4 運行結果
執行./skynet examples/Pconfig運行程序,結果如圖2-13所示。其中0100000b和16777227代表ping2的地址(一個十六進制一個十進制,它們是相同的值,根據不同配置,讀者看到的數值可能不同),0100000a和16777226代表ping1的地址。ping2先打印出計數值1,接著ping1打印出計數值2,然后ping2再打印出計數值3,以此類推。

圖2-13 PingPong程序的運行結果
- GAE編程指南
- Python概率統計
- C++程序設計(第3版)
- Cocos2D-X權威指南(第2版)
- Koa開發:入門、進階與實戰
- Learning Apache Mahout Classification
- 運用后端技術處理業務邏輯(藍橋杯軟件大賽培訓教材-Java方向)
- Kotlin編程實戰:創建優雅、富于表現力和高性能的JVM與Android應用程序
- Python機器學習之金融風險管理
- Node學習指南(第2版)
- Scratch趣味編程:陪孩子像搭積木一樣學編程
- 響應式Web設計:HTML5和CSS3實戰(第2版)
- Scala編程(第5版)
- C語言程序設計實訓教程與水平考試指導
- Python Machine Learning Blueprints:Intuitive data projects you can relate to