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