pomelo之因此簡單易用、功能全面,而且具備高可擴展性、可伸縮性等特色,這與它的技術選型和方案設計是密不可分的。在研究大量遊戲引擎設計思路基礎上,結合以往遊戲開發的經驗,肯定了pomelo框架的設計方案。javascript
node.js自身特色與遊戲服務器的特性驚人的吻合。 在node.js的官方定義中, fast、scalable、realtime、network這幾個特性都很是符合遊戲服務器的要求。遊戲服務器是個網絡密集型的應用,對實時性要求極高,而node.js在網絡io上的優點也徹底能夠知足這點。使用node.js開發遊戲服務器的優點總結:html
一個真正高可擴展的遊戲運行架構必須是多進程的。google的gritsgame, mozilla的browserquest 都採用了node.js做爲遊戲服務器開發語言, 但它們都採用了單進程的node.js服務器,缺少擴展性,這使它們能夠支撐的在線用戶數量是頗有限的(這兩個遊戲主要是做爲HTML5遊戲的demo)。而多進程的架構能夠很好的實現遊戲服務器的的擴展性,達到支撐較多在線用戶、下降服務器壓力等要求。前端
說明: 上圖中的方塊表示進程, 定義上等同於「服務器「java
該遊戲運行架構表面上看與web應用運行架構很相似,connector相似於web應用的apache/nginx等web服務器,後端的服務器羣相似於web應用中的應用服務器(如tomcat),但實際上存在着很大的差異:node
遊戲的運行架構很複雜,要想支撐起如此複雜的運行架構,必需要有一個框架來簡化開發。 pomelo正是這樣一個框架,它使咱們用最少的代碼, 最清晰的結構來實現複雜的運行架構。nginx
pomelo framework的組成架構如圖所示:git
在web應用中, 每一個服務器是無狀態、對等的, 開發者無需經過框架或容器來管理服務器。 但遊戲應用不一樣, 遊戲可能須要包含多種不一樣類型的服務器,每類服務器在數量上也可能有不一樣的需求。這就須要框架對服務器進行抽象和解耦,支持服務器類型和數量上的擴展。github
客戶端的請求、響應與web應用是相似的, 但框架是基於長鏈接的, 實現模式與http請求有必定差異。 廣播是遊戲服務器最頻繁的操做, 須要方便的API, 而且在性能上達到極致。web
儘管框架儘可能避免跨進程調用,但進程間的通信是不可避免的, 所以須要一個方便好用的RPC框架來支撐。ajax
* 鬆耦合、可插拔的應用架構。
應用的擴展性很重要, pomelo framework支持以component的形式插入任何第三方組件, 也支持加入自定義的路由規則, 自定義的filter等。
下面分別對這三個目標進行詳細的分析:
該架構把遊戲服務器作了抽象, 抽象成爲兩類:前端服務器和後端服務器, 如圖:
前端服務器(frontend)的職責:
後端服務器(backend)的職責:
動態語言的面向對象有個基本概念叫鴨子類型。 服務器的抽象也一樣能夠比喻爲鴨子, 服務器的對外接口只有兩類, 一類是接收客戶端的請求, 叫作handler, 一類是接收RPC請求, 叫作remote, handler和remote的行爲決定了服務器長什麼樣子。 所以咱們只要定義好handler和remote兩類的行爲, 就能夠肯定這個服務器的類型。
利用目錄結構與服務器對應的形式, 能夠快速實現服務器的抽象。
如下是示例圖:
圖中的connector, area, chat三個目錄表明三類服務器類型, 每一個目錄下的handler與remote決定了這個服務器的行爲(對外接口)。 開發者只要往handler與remote目錄填代碼, 就能夠實現某一類的服務器。這讓服務器實現起來很是方便。 讓服務器動起來, 只要填一份配置文件servers.json就可讓服務器快速動起來。 配置文件內容以下所示:
{
"development":{ "connector": [ {"id": "connector-server-1", "host": "127.0.0.1", "port": 3150, "clientPort":3010, "frontend":true}, {"id": "connector-server-2", "host": "127.0.0.1", "port": 3151, "clientPort":3011, "frontend":true} ], "area": [ {"id": "area-server-1", "host": "127.0.0.1", "port": 3250, "area": 1}, {"id": "area-server-2", "host": "127.0.0.1", "port": 3251, "area": 2}, {"id": "area-server-3", "host": "127.0.0.1", "port": 3252, "area": 3} ], "chat":[ {"id":"chat-server-1","host":"127.0.0.1","port":3450} ] } }
全部的web應用框架都實現了請求與響應的抽象。儘管遊戲應用是基於長鏈接的, 但請求與響應的抽象跟web應用很相似。 下圖的代碼是一個request請求示例:
請求的api與web應用的ajax請求很象,基於Convention over configuration的原則, 請求不須要任何配置。 以下圖所示,請求的route字符串:chat.chatHandler.send, 它能夠將請求分發到chat服務器上chatHandler文件定義的send方法。
Pomelo的框架裏還實現了request的filter機制,廣播/組播機制,詳細介紹見pomelo框架參考。
架構中各服務器之間的通信主要是經過底層RPC框架來完成的,該RPC框架主要解決了進程間消息的路由和RPC底層通信協議的選擇兩個問題。 服務器間的RPC調用也實現了零配置。實例以下圖所示:
上圖的remote目錄裏定義了一個RPC接口: chatRemote.js,它的接口定義以下:
chatRemote.kick = function(uid, player, cb) { }
其它服務器(RPC客戶端)只要經過如下接口就能夠實現RPC調用:
app.rpc.chat.chatRemote.kick(session, uid, player, function(data){ });
這個調用會根據特定的路由規則轉發到特定的服務器。(如場景服務的請求會根據玩家在哪一個場景直接轉發到對應的server)。 RPC框架目前在底層採用socket.io做爲通信協議,但協議對上層是透明的,之後能夠替換成任意的協議。
component是pomelo自定義組件,開發者可自加載自定義的component。 component在pomelo框架參考將有更深刻的討論。 如下是component的生命週期圖:
用戶只要實現component相關的接口: start, afterStart, stop, 就能夠加載自定義的組件:
app.load([name], comp, [opts])
上面的應用框架構成了pomelo framework的基礎。在此基礎上,配合pomelo提供的遊戲開發庫和相關工具集,開發遊戲服務器將變得很是方便。 後面的tutorial將帶咱們進入開發遊戲應用的實際案例。轉子
轉自:https://github.com/NetEase/pomelo/wiki/pomelo%E6%9E%B6%E6%9E%84%E6%A6%82%E8%A7%88#%E4%B8%80%E4%B8%AA%E5%85%B8%E5%9E%8B%E7%9A%84%E5%A4%9A%E8%BF%9B%E7%A8%8Bmmo%E8%BF%90%E8%A1%8C%E6%9E%B6%E6%9E%84-%E5%A6%82%E4%B8%8B%E5%9B%BE%E6%89%80%E7%A4%BA