• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2017年1月>
            25262728293031
            1234567
            891011121314
            15161718192021
            22232425262728
            2930311234


            專注即時(shí)通訊及網(wǎng)游服務(wù)端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標(biāo)準(zhǔn)模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉(zhuǎn)載,并在文章開頭給出了原文出處,如有再轉(zhuǎn),敬請保留相關(guān)信息,這是大家對(duì)原創(chuàng)作者勞動(dòng)成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            相冊

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 219196
            • 排名 - 117

            最新評(píng)論

            閱讀排行榜

            http://www.infoq.com/cn/articles/game-server-development-3


            在上一篇文章中,我們介紹了如何使用Pomelo來搭建聊天服務(wù)器。在這篇文章中,我們?yōu)榇蠹医榻B如何使用Pomelo框架來搭建MMO RPG服務(wù)器,并分析其設(shè)計(jì)思路和實(shí)現(xiàn)方法。以此來幫助大家更好的理解和使用Pomelo框架,理解Pomelo框架游戲開發(fā)的基礎(chǔ)流程,使用方法和設(shè)計(jì)理念。

            本文中的游戲服務(wù)端架構(gòu),只是為了說明Pomelo的開發(fā)理念和設(shè)計(jì)思路,并不是基于Pomelo開發(fā)的唯一方案,開發(fā)者完全可以根據(jù)自己的實(shí)際應(yīng)用環(huán)境設(shè)計(jì)不同的服務(wù)端架構(gòu)。

            開始之前

            Pomelo框架與MMO RPG

            我們曾在本系列第一篇文章曾介紹過pomelo的架構(gòu)。我們先簡單回顧一下Pomelo為我們的游戲開發(fā)提供了什么:

            相關(guān)贊助商

            QCon北京2016大會(huì),4月21-23日,北京·國際會(huì)議中心,精彩內(nèi)容邀您參與!

            • 可擴(kuò)展的服務(wù)器架構(gòu)。Pomelo中對(duì)服務(wù)器端進(jìn)行了抽象,將服務(wù)器分為承載鏈連接的前端服務(wù)器和負(fù)責(zé)業(yè)務(wù)邏輯的后端服務(wù)器,并提供了便利,高效的分布式擴(kuò)展支持,讓使用者可以在少改甚至不改的前提下實(shí)現(xiàn)對(duì)服務(wù)端的擴(kuò)展。
            • 完整的通信框架:Pomelo對(duì)客戶端與服務(wù)器之間,服務(wù)器與服務(wù)器之間的通信進(jìn)行了完整的封裝。開發(fā)者只需要按照默認(rèn)規(guī)則來填寫服務(wù)代碼就可以完成接口的發(fā)布和調(diào)用,而不用考慮內(nèi)部實(shí)現(xiàn)。
            • 大量游戲開發(fā)基礎(chǔ)庫:除了基本的服務(wù)器框架之外,Pomelo還提供了很多游戲開發(fā)需要用到的基礎(chǔ)庫,如任務(wù)調(diào)度,AI控制,尋路等,而這些庫還會(huì)隨著Pomelo的發(fā)展進(jìn)一步完善。
            • 基于Node.JS輕量級(jí)的開發(fā)環(huán)境,以及大量的模塊。相對(duì)于傳統(tǒng)的開發(fā)語言,Node.JS有著輕量,快捷的特性(0.3版中啟動(dòng)一個(gè)包括10幾個(gè)服務(wù)器集成的服務(wù)端只需要不到4S)。而活躍的開源社區(qū)也提供了大量的第三方模塊。

            作為Pomelo游戲開發(fā)的入門導(dǎo)引,本文的重點(diǎn)將放在游戲基礎(chǔ)架構(gòu)的搭建上,因此本文將主要介紹下面三個(gè)方面的內(nèi)容:游戲服務(wù)端的構(gòu)建,與客戶端的通訊,服務(wù)器的擴(kuò)展。

            本文的參考示例

            我們使用demo Treasures作為本文的參考示例,游戲的截圖如下:

            從上圖可以看出,在treasures中,玩家會(huì)進(jìn)入一張遍布寶物的地圖中,通過拾取寶物來獲得積分。所有玩家的積分在右上角會(huì)有一個(gè)排名。下面是這個(gè)demo的關(guān)鍵點(diǎn):

            • 每個(gè)玩家的行動(dòng)對(duì)其他玩家來看都是實(shí)時(shí)的。
            • 在獲取寶物時(shí)積分會(huì)更新積分榜,這個(gè)更新對(duì)所有玩家實(shí)時(shí)可見。
            • 寶物會(huì)定時(shí)刷新。

            相對(duì)于一般的的MMO RPG,這個(gè)demo顯得十分簡陋:沒有持久化,沒有戰(zhàn)斗,沒有AI。。。但是,其中實(shí)現(xiàn)了MMO RPG中最核心的亮點(diǎn)功能:一個(gè)可以容納多個(gè)在線玩家的游戲場景,以及玩家之間的實(shí)時(shí)互動(dòng)。那些功能的確實(shí)可以讓系統(tǒng)的結(jié)構(gòu)更加清晰明確,成為一個(gè)非常好的項(xiàng)目導(dǎo)引。

            搭建游戲服務(wù)端

            由于游戲邏輯十分簡單,我們后端采用一臺(tái)單獨(dú)的場景服務(wù)器來運(yùn)行整個(gè)游戲邏輯,同時(shí)加入一臺(tái)連接服務(wù)器來承載用戶連接,系統(tǒng)的設(shè)計(jì)如下:

            下面,我們就按照這個(gè)設(shè)計(jì)來搭建游戲服務(wù)端。

            編寫場景服務(wù)

            游戲場景是玩家所處的虛擬環(huán)境,而場景服務(wù)器就是游戲場景在服務(wù)端的抽象,根據(jù)游戲類型和內(nèi)容的不同,場景服務(wù)器的復(fù)雜程度也會(huì)千差萬別。在我們的例子中,場景的構(gòu)成十分簡單:一張開放的游戲地圖,地圖中的玩家,以及定時(shí)刷新的寶物。

            首先,作為一個(gè)場景服務(wù)器,需要能夠儲(chǔ)存用戶和寶物的信息,這里我們直接使用一個(gè)放在內(nèi)存中的map來儲(chǔ)存場景中的所有實(shí)體,同時(shí),我們將所有場景中的實(shí)體都抽象為一個(gè)Entity對(duì)象,放在這個(gè)map中。

            為了能夠操縱這些數(shù)據(jù),還需要暴露出對(duì)外接口,我們使用的接口有下面三種:

            • 初始化的接口:我們在init方法中會(huì)設(shè)置場景信息,配置參數(shù)等,并啟動(dòng)場景中的時(shí)鐘循環(huán)。
            • 實(shí)體訪問接口:如AddEntity和RemoveEntity接口等,我們使用這些接口來訪問和修改場景中的實(shí)體。
            • 刷新場景中的寶物:當(dāng)滿足條件時(shí),外部事件會(huì)調(diào)用該接口來刷新地圖中的寶物。

            我們通過一個(gè)無限循環(huán)的tick來驅(qū)動(dòng)場景服務(wù),在每一個(gè)tick中會(huì)更新場景中所有實(shí)體的狀態(tài)信息,我們最終設(shè)計(jì)如下:

            搭建場景服務(wù)器

            在完成場景服務(wù)的代碼之后,我們還需要提供一個(gè)場景服務(wù)運(yùn)行的平臺(tái),在Pomelo中,我們通過搭建一個(gè)場景服務(wù)器來實(shí)現(xiàn)。

            Pomelo中的服務(wù)器分為兩類,負(fù)責(zé)承載用戶連接的前端服務(wù)器和運(yùn)行邏輯的后端服務(wù)器。作為負(fù)責(zé)核心邏輯的場景服務(wù)器,自然是屬于后端服務(wù)器,因此,我們在/game-sever/config/server.json中加入以下配置:

            "area": [ {"id": "area-server-1", "host": "127.0.0.1", "port": 3250, "areaId": 1} ]

            其中的“area”是我們?yōu)閳鼍胺?wù)器類型所起的名稱,其對(duì)應(yīng)的內(nèi)容就是場景服務(wù)器的列表,可以看出,現(xiàn)在我們只加入了單臺(tái)場景服務(wù)器。與聊天服務(wù)器相比,場景服務(wù)器的配置并沒有明顯區(qū)別,只是多了一個(gè)areaId的屬性。我們使用這一屬性來標(biāo)明這個(gè)場景服務(wù)器對(duì)應(yīng)的場景id,我們的建議設(shè)計(jì)是一個(gè)游戲服務(wù)器對(duì)應(yīng)一個(gè)獨(dú)立的游戲場景,這樣可以大大減少場景管理的開銷,并提高單場景的負(fù)載能力。Pomelo中每一個(gè)服務(wù)器就是一個(gè)獨(dú)立的進(jìn)程,相對(duì)于一個(gè)場景服務(wù)的開銷,單獨(dú)的服務(wù)器造成的開銷是可以接受的。當(dāng)然,這只是建議設(shè)計(jì),框架本身完全支持一個(gè)游戲服務(wù)器對(duì)應(yīng)多個(gè)游戲場景的設(shè)計(jì)。開發(fā)者可以根據(jù)具體的應(yīng)用情況調(diào)整場景服務(wù)器的配置,通過加入場景管理邏輯,實(shí)現(xiàn)一個(gè)場景服務(wù)器和場景之間的自由配置。

            啟動(dòng)場景服務(wù)

            在加入場景服務(wù)器之后,我們還需要對(duì)服務(wù)端的運(yùn)行環(huán)境進(jìn)行配置,在場景服務(wù)器啟動(dòng)時(shí)運(yùn)行對(duì)應(yīng)的場景服務(wù)。為了實(shí)現(xiàn)這一目標(biāo),我們需要在app.js中加入如下配置:

            app.configure('production|development', 'area', function(){ var areaId = app.get('curServer').areaId; area.init(dataApi.area.findById(areaId)); });

            app.configure方法用來對(duì)指定的服務(wù)器進(jìn)行配置,包括三個(gè)參數(shù),前兩個(gè)參數(shù)分別是運(yùn)行環(huán)境和服務(wù)器類型的filter,第三個(gè)參數(shù)是在滿足前面兩個(gè)filter的情況下需要運(yùn)行的代碼。在上面的配置中,第一個(gè)參數(shù)"production|development"表示是針對(duì)線上和開發(fā)兩種環(huán)境,之后的‘area’參數(shù)表示的是針對(duì)area服務(wù)器類型。 關(guān)于app.js初始化的更多內(nèi)容,見 其中的標(biāo)志位“frontend:true”表示這是一個(gè)前端服務(wù)器,“clientPort:3010”則表示該服務(wù)器對(duì)外暴露前端。對(duì)于前端服務(wù)器,在啟動(dòng)時(shí)就會(huì)默認(rèn)加載連接組件,因此我們不需要在app.js中進(jìn)行額外的配置。在pomelo 0.3中,如果需要使用原生websocket等非默認(rèn)的連接方式,則需要在app.js中加入相應(yīng)配置。在客戶端,我們在啟動(dòng)時(shí)連接對(duì)應(yīng)的接口,就可以建立起與服務(wù)端的連接。

            處理客戶端請求

            Pomelo中,我們提供了兩種客戶端向服務(wù)端發(fā)送請求的方法,request/response模式和notify模式。

            request/response 模式與web中的請求模式相似,是標(biāo)準(zhǔn)的請求/響應(yīng)模式,對(duì)于客戶端的一個(gè)請求,服務(wù)端會(huì)給出一個(gè)響應(yīng)。以玩家的移動(dòng)為例,當(dāng)需要移動(dòng)時(shí),會(huì)發(fā)送一個(gè)請求給服務(wù)端,服務(wù)端會(huì)驗(yàn)證客戶端的請求,并返回結(jié)果客戶端,下圖是具體請求流程:

            最上面的是客戶端代碼,在這里,我們向服務(wù)端發(fā)送一個(gè)移動(dòng)請求。 之后,服務(wù)端會(huì)根據(jù)請求的route(area.playerHandler.move)找到對(duì)應(yīng)的處理方法(/game-server/area/handler/playerHander.move),然后調(diào)用該方法來處理客戶端的請求。當(dāng)處理完成之后,會(huì)并在next方法中傳入處理結(jié)果,結(jié)果會(huì)發(fā)回客戶端,并作為回調(diào)函數(shù)的參數(shù)傳回。

            notify模式的運(yùn)行流程與request/response類似,只是當(dāng)服務(wù)端處理請求后不會(huì)發(fā)送任何響應(yīng)。客戶端通過pomelo.notify方法來發(fā)出notify請求,notify請求的參數(shù)與pomelo.request相似,只是不需回調(diào)函數(shù),notify方法的實(shí)例如下:

            ``` pomelo.notify('area.playerHandler.pick', params); ``` 

            服務(wù)端消息推送

            與web服務(wù)不同,game服務(wù)端會(huì)有大量的推送消息,要實(shí)現(xiàn)這一功能,我們使用pomelo中的push模式來實(shí)現(xiàn)。下圖以“move”為例,展示了服務(wù)端的推送流程:

            Treasures中的廣播功能是通過一個(gè)全局的channel來實(shí)現(xiàn)的,在游戲中的所有玩家在加入游戲后都會(huì)加入一個(gè)全局的channel中。當(dāng)需要廣播消失時(shí),服務(wù)端就會(huì)調(diào)用這個(gè)全局的channel來對(duì)所有用戶進(jìn)行消息推送。

            擴(kuò)展游戲服務(wù)端

            在前面兩節(jié)中,我們使用pomelo搭建了一個(gè)單節(jié)點(diǎn)的游戲服務(wù)器。在這一節(jié)中,將介紹如何使用Pomelo來對(duì)服務(wù)端進(jìn)行擴(kuò)展,搭建分布式的游戲服務(wù)。

            由于游戲服務(wù)器的復(fù)雜性,像web服務(wù)器簡單的水平擴(kuò)展是不現(xiàn)實(shí)的,而根據(jù)業(yè)務(wù)邏輯的不同,不同的服務(wù)器也有著不同的擴(kuò)展方案。因此我們分別以前面介紹的連接服務(wù)器和場景服務(wù)器為例,來對(duì)他們進(jìn)行擴(kuò)展。

            連接服務(wù)器的擴(kuò)展

            連接服務(wù)器作用是負(fù)責(zé)維護(hù)所有客戶端的連接,負(fù)責(zé)客戶端消息的接受和推送,在MMO RPG中,連接服務(wù)器往往是性能的熱點(diǎn)之一,因此對(duì)連接服務(wù)器的擴(kuò)展對(duì)于提高系統(tǒng)負(fù)載有很重要的現(xiàn)實(shí)意義。 在例子treasures中,我們通過加入一個(gè)負(fù)載均衡服務(wù)器(gate服務(wù)器),來實(shí)現(xiàn)連接服務(wù)器的擴(kuò)展:當(dāng)客戶端登錄時(shí),會(huì)首先連接gate服務(wù)器,來分配一個(gè)連接服務(wù)器,之后,客戶端會(huì)斷開與gate服務(wù)器的連接,在與其對(duì)應(yīng)的連接服務(wù)器建立連接,如下圖所示:

            要實(shí)現(xiàn)這一功能,在服務(wù)端,我們首先要在server.config中加入新的前端服務(wù)器,代碼如下:

            ``` "gate": [   {"id": "gate-server-1", "host": "127.0.0.1", "clientPort": 3014, "frontend": true} ] ``` 

            之后,在gate服務(wù)器上編寫對(duì)應(yīng)的負(fù)載均衡接口,在例子中,我們采用了使用uid的crc值對(duì)服務(wù)器數(shù)目取模的方式,代碼如下:

            ``` module.exports.dispatch = function(uid, connectors) {     var index = Math.abs(crc.crc32(uid)) % connectors.length;     return connectors[index]; }; ``` 

            最后,在客戶端加入對(duì)應(yīng)的連接代碼,就完成了對(duì)連接服務(wù)器的擴(kuò)展。 在我們的例子中只用到了兩臺(tái)連接服務(wù)器,而在實(shí)際應(yīng)用中,可以根據(jù)實(shí)際環(huán)境,編寫自己的負(fù)載均衡算法,加入更多的連接服務(wù)器。

            場景服務(wù)器的擴(kuò)展

            與連接服務(wù)器不同,場景服務(wù)器中包含著大量的狀態(tài)信息,如果對(duì)單一的場景進(jìn)行擴(kuò)展,需要復(fù)雜的同步機(jī)制和大量遠(yuǎn)程調(diào)用。因此,在Pomelo中,我們的場景擴(kuò)展是通過加入新的場景來進(jìn)行的。 在設(shè)計(jì)游戲時(shí),整個(gè)世界就被分為多個(gè)不同的場景。而在服務(wù)器端,一個(gè)場景則與一個(gè)獨(dú)立的場景服務(wù)器相對(duì)應(yīng),場景服務(wù)的擴(kuò)展可以通過加入新的場景來完成。下面,就以treasure為例,介紹一下場景服務(wù)的的擴(kuò)展方法: 因?yàn)閳鼍皵U(kuò)展是通過加入新的場景來完成的,所以首先要在server.json中加入新的場景服務(wù)器:

            在加入場景服務(wù)器之后,我們還要保證發(fā)往場景服務(wù)器的請求可以被分發(fā)到正確的場景去。而Pomelo中,對(duì)于同一類型的服務(wù)器,默認(rèn)的分法方法是采用隨機(jī)分配的方式,這是不能滿足我們要求的。因此,我們需要加入自己的路由算法,流程如下:

            首先,我們編寫了新的路由算法:根據(jù)用戶所屬的場景id進(jìn)行投遞。之后,我們在app.js中使用app.route方法來將我們的路由算法配置為針對(duì)area服務(wù)器的默認(rèn)方法。app.route方法接受兩個(gè)參數(shù),第一個(gè)是需要自定義route的服務(wù)器類型,第二個(gè)參數(shù)就是具體的路由算法。我們分別將‘area’服務(wù)類型和我們編寫的算法傳入,就可以實(shí)現(xiàn)自定義的路由功能了。

            跨平臺(tái)客戶端

            除了原有的JS客戶端之外,pomelo還提供了多種其他的客戶端,而不同的客戶端可能會(huì)對(duì)應(yīng)著不同的長連接協(xié)議。但是經(jīng)過pomelo封裝之后,在Pomelo服務(wù)端,不同客戶端在連接上連接上是完全對(duì)等的。因此,你可以使用pomelo框架實(shí)現(xiàn)跨平臺(tái)聯(lián)機(jī)對(duì)戰(zhàn)的(前提是你開發(fā)了針對(duì)多個(gè)平臺(tái)的游戲客戶端)。

            最終架構(gòu)

            經(jīng)過擴(kuò)展后,我們的最終服務(wù)器架構(gòu)如圖所示:

            總結(jié)

            在本文中,我們介紹了如何使用Pomelo框架來構(gòu)建了一個(gè)包括連接服務(wù)器和場景服務(wù)器的MMO RPG服務(wù)端。并介紹了如何使用pomelo特性,來對(duì)游戲服務(wù)端進(jìn)行擴(kuò)展,并構(gòu)建出了一個(gè)分布式的MMO RPG服務(wù)。 但是,這只是游戲服務(wù)端開發(fā)中最為基礎(chǔ)的部分,MMO RPG中很多基礎(chǔ)功能在這里都沒有實(shí)現(xiàn),如數(shù)據(jù)持久化,AI控制,尋路系統(tǒng)等。在下面的文章中,我們會(huì)進(jìn)一步介紹Pomelo在游戲開發(fā)中的應(yīng)用。

            參考示例

            撿寶demo

            Pomelo啟動(dòng)流程

            Pomelo框架

            posted on 2016-03-14 09:14 思月行云 閱讀(402) 評(píng)論(0)  編輯 收藏 引用 所屬分類: Node.js
            国产精品99久久久精品无码| 久久久久久国产a免费观看黄色大片| 2021国产精品午夜久久| 久久99精品久久久久久久久久| 日韩精品久久久久久| 99久久这里只精品国产免费| 国产一区二区精品久久| 国产精品亚洲综合久久 | 91麻精品国产91久久久久| 久久精品国产亚洲精品2020| 久久人人爽人人爽人人片AV东京热| 亚洲色大成网站WWW久久九九| 高清免费久久午夜精品| 99久久综合狠狠综合久久| 97精品依人久久久大香线蕉97| 久久99国内精品自在现线| 免费精品久久久久久中文字幕| 久久免费视频网站| 国产精品国色综合久久| 国产色综合久久无码有码| 亚洲а∨天堂久久精品9966| 久久99精品国产麻豆婷婷| 久久精品国产免费| 久久精品国产亚洲麻豆| 久久久久久无码Av成人影院| 综合网日日天干夜夜久久 | 韩国免费A级毛片久久| 少妇久久久久久被弄高潮| 色妞色综合久久夜夜| 久久人人爽人人爽人人片AV不 | 18禁黄久久久AAA片| 久久亚洲精品国产亚洲老地址 | 久久一区二区三区免费| 精品无码人妻久久久久久| 久久99久久成人免费播放| 久久亚洲色一区二区三区| 久久这里有精品视频| 久久综合久久美利坚合众国| 人妻精品久久无码专区精东影业| 无码人妻精品一区二区三区久久 | 国产叼嘿久久精品久久|