這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
GoWorld是一個使用Golang實現的可擴充的分布式遊戲伺服器引擎,並支援遊戲邏輯的熱更新。
GoWorld代碼:https://github.com/xiaonanln/goworld
進程結構
GoWorld架構圖
一個GoWorld系統包括一個dispatcher進程、一個或者多個game進程以及一個或者多個gate進程。dispatcher負責game之間以及gate和game之間的訊息轉寄,並對一些基礎功能提供支援。Game進程負責Entity對象的管理和所有遊戲邏輯的運行,Gate進程負責管理用戶端串連,並將用戶端請求通過dispatcher轉寄到game進程。Gate還需要負責對用戶端資料進行壓縮和加解密(尚未實現)。GoWorld可以通過增加更多的game進程或者gate進程來增加伺服器的負載能力。雖然dispatcher進程是GoWorld伺服器中的單點,但是初步的測試和推算表明一個多核高效能的主機上運行dispatcher可以支援100萬以上的同時線上。
熱更新
GoWorld使用Hot-Swappaing的方式實現遊戲邏輯的熱更新。在Game進程收到SIGUSR1訊號的時候,就會把當前所有Entity以及其他相關狀態儲存到一個檔案中,並結束進程。此時可以使用最新的可執行鏡像重啟game進程,並從儲存的檔案中恢複所有的Entity和遊戲狀態,並恢複執行。在熱更新的過程中,玩家用戶端的串連不會中斷,玩家角色的狀態也會保持不變,只是會感受到一點卡頓,並在熱更新結束後恢複。
Entity架構
Entity RPC
在GoWorld中,我們使用一個Entity來代表遊戲情境中的玩家、怪物、NPC之類的對象。GoWorld還支援從用戶端到服務端的RPC通訊,以及服務端Entity之間的RPC通訊。
GoWorld在RPC資料的封包和解析上使用了MessagePack格式,並會在將來支援Google Protobuf。
情境
情境(Space)是GoWorld中一個非常重要的概念。每個Entity都屬於一個情境。同一個情境的Entity之間可以直接調用相互的函數,而跨情境的Entity之間需要使用RPC來進行通訊。Entity可以通過遷移(Migrate)函數來跳轉到別的情境中,跳轉情境後Entity的所有屬性資料都將保持不變。
AOI
GoWorld提供了一套簡化的AOI機制。同情境的Entity之間會根據距離維護一個鄰居列表。GoWorld使用十字列表維護情境裡的所有Entity,從而根據Entity的位置變化即時更新所有Entity的AOI資訊。
屬性同步
GoWorld為Entity提供了屬性機制。屬性分為服務端屬性、用戶端屬性和全域屬性。服務端屬性只有在服務端可以訪問,用戶端屬性可以在用戶端和服務端同時訪問。每次服務端對其進行修改的時候,屬性的變化會立刻被同步到用戶端,從而保持用戶端資料的即時更新。全域屬性是對所有Entity都可見的資料,包括其他玩家。全域屬性在發生變化的時候會被廣播到AOI範圍內的所有玩家,從而使得玩家可以即時擷取AOI範圍內其他Entity的屬性變化。
Entity存檔和載入
GoWorld支援Entity的自動存檔。持久化(persistent)的Entity會按一定的時間間隔進行存檔。GoWorld還提供了對已存檔Entity的載入功能。目前GoWorld支援MongoDB和Redis兩種不同的底層資料庫。
用戶端串連和通訊
每個server都會建立一個監聽連接埠用於接收來自用戶端的串連。用戶端和服務端之間也採用一個RPC的通訊方式。用戶端可以對玩家和玩家AOI裡的其他Entity發起RPC調用。
GoWorld支援對用戶端通訊進行壓縮。加密功能還有待添加。。。
還在開發階段,更多內容有待補充,敬請關注 ……