Skip to content
This repository has been archived by the owner on Sep 25, 2023. It is now read-only.

Pomelo 0.3新特性

xiecc edited this page Mar 5, 2013 · 15 revisions

#Pomelo 0.3版本新特性

Pomelo 0.3版为移动端性能优化做了很多工作, 数据包压缩后的传输量仅为0.2版的十分之一, 并仍然保存了支持之前基于socket.io的传输协议。这使开发同时支持浏览器、移动客户端等多种客户端的高实时系统或游戏变得非常容易。

服务器的动态扩展是另一个重要的特性, 这不仅使系统适应了弹性的工作环境,也为游戏的一些动态功能提供了更多方便, 如MMORPG游戏的动态副本等。

0.3版还提供了其它很多特性,如新的广播接口, 新的客户端支持等。

##1 新协议支持

0.3版Pomelo开始支持二进制协议,并支持对请求route的字典压缩和请求内容进行protobuf压缩。0.3版同时兼容以前版本基于socket.io的通讯协议。通过在应用中配置不同的connector component来实现协议的切换或共存。

目前Pomelo服务器提供两类connector:sioconnector和hybridconnector,分别对于基于socket.io和二进制的通讯。

###1.1 sioconnector

支持基于socket.io的通讯协议,也是Pomelo框架默认采用的connector(主要是兼容老版本)。之前基于socket.io的服务器和客户端代码不用修改就可以使用。

###1.2 hybridconnector

支持socket和websocket,使用二进制通讯协议,并且支持route字典压缩和protobuf压缩的connector,需要在app.js中显式配置。以下是一个hybridconnector的配置例子:

app.configure('production|development', 'connector', function(){
  app.set('connectorConfig', {
    connector: pomelo.connectors.hybridconnector,
    heartbeat: 3,
    useDict: true,
    useProtobuf: true,
    checkClient: function(type, version) {
    	// check the client type and version then return true or false
    },
    handshake: function(msg, cb){
      cb(null, {/* message pass to client in handshake phase */});
    }
  });
});

首先,通过app.set('connectorConfig', opts)更改了connector组件的默认配置。opts是最终将被传递给connector,不同的connector可以有不同的opts内容。

  • connector - 指定所采用的connector实现,用来支持不同的底层通讯协议。Pomelo提供了pomelo.connectors.sioconnectorpomelo.connectors.hybridconnector。开发者也可以实现自己的connector,以支持不同的通讯协议。
  • heartbeat - 客户端与服务器的心跳间隔。不指定则表示不需要心跳。具体心跳流程在协议文档心跳小结介绍。
  • useDict - 是否进行route字典压缩,默认为false。具体字典压缩原理请参考协议文档字典压缩小结。
  • useProtobuf - 是否对协议内容进行protobuf压缩,默认为false。protobuf的流程请参考协议文档protobuf压缩小结。
  • checkClient - 可选的客户端鉴定函数。如果设置该字段,则要求客户端在握手阶段必须传递其版本号给服务器,并通过此函数来鉴定该版本客户端是否适用。如果该函数的返回值为false,则拒绝该客户端的后续操作。
  • handshake - 可选的握手函数,在客户端和服务器握手过程中被调用,用来在握手阶段向客户端传递自定义的信息。

###1.3 不同connector的共存

不同的connector可以在同一个项目中共存,支持不同的客户端连接,只要配置不同的前端服务器,监听不同的端口即可。例如:

// frontend server based on socket.io
app.configure('production|development', 'sio-connector', function(){
  app.set('connectorConfig', {
    connector: pomelo.connectors.sioconnector
  });
});

// frontend server based on socket and websocket
app.configure('production|development', 'hybrid-connector', function(){
  app.set('connectorConfig', {
    connector: pomelo.connectors.hybridconnector
  });
});

servers.json的配置

{
  "development": {
    "sio-connector": [
      {"id": "sio-server-1", "host": "127.0.0.1", "port": 3150, "clientPort": 3010, "frontend": true}
    ],
    "hybrid-connector": [
      {"id": "hybrid-server-1", "host": "127.0.0.1", "port": 3250, "clientPort": 3020, "frontend": true}
    ]
  }
}

关于Pomelo二进制协议的具体格式,请参考Pomelo协议文档

##2 动态服务器扩展 Pomelo 0.3版开始支持动态增加和移除服务器进程机制,并提供相应的命令行工具。每台新增的服务器都会连接到master服务器上进行注册。Master再将新服务器的信息广播给集群中的所有服务器进程。原有的服务器进程再对新增服务器事件进行响应。

当一个服务器进程接收到一个新增服务器的消息后,会将该服务器信息保存到本地的app上下文中,之后可以通过app.getServers等系列方法查看到新服务器的信息,从而影响之后的消息路由。

如果新加的服务器的类型之前尚未存在于app上下文中,Pomelo会尝试着为其创建对应的rpc代理对象。如果该类型服务器需要提供rpc服务,则需要在约定的目录(servers/server-type/remote/)下提供rpc服务代码。

动态移除服务器进程的流程也与上面类似,当服务器断开与master的连接后,master会将该服务器的信息广播给其他进程,其他进程再进行相应处理。

注意: Pomelo仅提供动态增加和移除服务器进程的机制,但由此而导致的路由规则的变化应当由具体的应用自己来维护。需要谨慎处理好诸如数据状态等问题。

###命令行支持

Pomelo 0.3版本的命令行工具根据新特性增加了一个add命令,同时对之前的stop命令做了一定的修改。

pomelo add命令主要作用是动态的添加服务器,暂时不支持前端服务器的添加(0.3后面的版本可能会支持)。命令需要的参数有四个,分别是服务器地址,服务器端口号,服务器id(用来标识服务器),服务器类型;具体的命令格式:pomelo add host=[host] port=[port] id=[id] serverType=[serverType]。

pomelo stop命令主要作用是动态的停止服务器,可以动态的停止某一台服务器或者同时停止多台服务器。命令主要需要的参数就是服务器id,具体的命令格式:pomelo stop [id], 可以同时有多个id,这样就是停止多台服务器,如果没有id,默认就是停止所有的服务器。

##3 其他新特性

###3.1 servers.json配置文件的修改

随着Pomelo支持协议的增多,配置文件原先定义的wsPort(代表websocket port)已不适用,现调整为clientPort。并新增一个字段frontend来标识该服务器是否是前端服务器,前端服务器必须设置该字段为true,后端服务器可以不设置或设置成false。

lordofpomelo为例,servers.js文件修改如下。

connector服务器配置:

"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}
]

gate服务器配置:

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

服务器代码中有依赖到配置信息wsPort的地方也需要做相应的调整。lordofpomelo中的gateHandler中的res.wsPort需要改为res.clientPort

###3.2 新增channel广播接口

ChannelService新增broadcast接口,适用于给全世界广播的场景。该接口会将消息推送到指定类型的所有前端服务器进程,再由后者将消息推送给连接的所有客户端。

使用例子:

var frontendType = 'connector';
var route = 'test.hello';
var msg = {msg: 'hello world'};
var bindedClient = true;
app.get('channelService').broadcast(frontendType, route, msg, bindedClient, function(err) {
  // check the broadcast result
});

###3.3 新增session获取接口

LocalSessionService新增根据session id获取localSession接口get和根据user id获取localSession接口getByUid

使用例子:

var frontendId = 'connector-server-1';
var sid = 1;
var uid = '123456';
app.get('localSessionService').get(frontendId, sid, function(err, localSession) {
  // do something with the local session
});

app.get('localSessionService').getByUid(frontendId, uid, function(err, localSession) {
  // do something with the local session
});

###3.4 客户端build系统

TODO

Clone this wiki locally