使用pomelo做服务器开发时,无论什么客户端,只要遵循与服务器的线上协议就能够与服务器建立通信。pomelo内置sioconnector、hybirdconnector都定义了自己的协议格式。
配置服务器通信协议
$ vim game-server/app.js
const pomelo = require('pomelo');
/**
* 初始化应用
*/
const app = pomelo.createApp();
app.set('name', 'test');
//前端服务器配置
app.configure('production|development', 'connector', function(){
//连接配置
app.set('connectorConfig',
{
connector : pomelo.connectors.hybridconnector,
heartbeat : 3,
useDict : true,
useProtobuf : true
});
});
//开启应用
app.start();
process.on('uncaughtException', function (err) {
console.error(' Caught exception: ' + err.stack);
});
Pomelo支持的通信协议
在与客户端通信时pomelo提供了hybirdconnector和sioconnector,hybirdconnector支持TCP、WebSocket,sioconnector支持socket.io。实际编程中,可使用pomelo提供的接口自定义connector。
前端服务器 | 类 | 协议 | 通信 | 适用范围 |
---|---|---|---|---|
hybirdconnector | pomelo.connectors.hybirdconnector | TCP、WebSocket | 使用二进制通信 | 移动端 |
sioconnector | pomelo.connectors.sioconnector | socket.io | 使用JSON通信 | PC端 |
udpconnector | pomelo.connectors.udpconnector | UDP | 二进制协议 | 网路环境差数据包小的环境 |
mqttconnector | pomelo.connectors.mqttconnector | MQTT | 二进制物联网协议 | 嵌入式设备 |
pomelo内部有各种协议的实现,典型的有protobuf、mqtt。mqtt物联网协议的特点是体积小、效率高、省电,pomelo+mqtt能实现单机30w在线的推送。
Web端JavaScript开发库
对于浏览器来说,HTML5中已经支持了WebSocket,因此使用支持WebSocket的浏览器可以直接与服务器的hybirdconnector建立通信。对于比较旧的浏览器,还没有支持websocket的可使用基于socket.io的方式与服务器建立连接。因此,对于Web端,Pomelo提供了两套开发库,分别适用于支持WebSocket的浏览器和不支持WebSocket的浏览器。
开发库 | 描述 |
---|---|
pomelo-jsclient-socket.io | 适用于socket.io |
pomelo-jsclient-websocket | 适用于websocket |
无论是socket.io还是websocket都提供了统一的API
pomelo.init(params, cb);
客户端pomelo初始化,在客户端第一次调用时使用。参数params中需要指定连接的服务器的主机地址和端口,回调函数cb在连接成功后会进行回调。
pomelo.init = function(params, cb){
pomelo.params = params;
params.debug = true;
var host = params.host;
var port = params.port;
var url = 'ws://' + host;
if(port) {
url += ':' + port;
}
socket = io(url, {'force new connection': true, reconnect: false});
socket.on('connect', function(){
console.log('[pomeloclient.init] websocket connected!');
if (cb) {
cb(socket);
}
});
socket.on('reconnect', function() {
console.log('reconnect');
});
socket.on('message', function(data){
if(typeof data === 'string') {
data = JSON.parse(data);
}
if(data instanceof Array) {
processMessageBatch(pomelo, data);
} else {
processMessage(pomelo, data);
}
});
socket.on('error', function(err) {
console.log(err);
});
socket.on('disconnect', function(reason) {
pomelo.emit('disconnect', reason);
});
};
pomelo.request(route, msg, cb);
request
用于请求服务,route
是服务端的路由,格式为"xxx.xxx.xxx"。msg
为请求内容,cb
响应回来后的回调函数。
参数 | 描述 |
---|---|
route | 服务端的路由,格式为"xxx.xxx.xxx"。 |
msg | 请求内容 |
cb | 响应成功后的回调函数 |
pomelo.request = function(route) {
if(!route) {
return;
}
var msg = {};
var cb;
arguments = Array.prototype.slice.apply(arguments);
if(arguments.length === 2){
if(typeof arguments[1] === 'function'){
cb = arguments[1];
}else if(typeof arguments[1] === 'object'){
msg = arguments[1];
}
}else if(arguments.length === 3){
msg = arguments[1];
cb = arguments[2];
}
msg = filter(msg,route);
id++;
callbacks[id] = cb;
var sg = Protocol.encode(id,route,msg);
socket.send(sg);
};
例如:同网关服务器建立连接后 ,向其发送查询前端服务器入口的请求。
/**
* 连接gate服务器
* 客户端首先要给gate服务器查询一个connector服务器,gate给其回复一个connector的地址及端口号
* */
function queryEntry(data, callback){
const config = {host:"127.0.0.1", port:3014, log:true};
pomelo.init(config, function(socket){
const route = "gate.gateHandler.queryEntry";
pomelo.request(route, data, function(msg){
pomelo.disconnect();
if(!msg){
msg = {code:500, msg:"error"};
}
callback(msg);
});
});
}
pomelo.disconnect();
disconnect()
方法用于Pomelo主动断开连接
pomelo.disconnect = function() {
if(socket) {
socket.disconnect();
socket = null;
}
};
on()
方法用于从EventEmmiter
继承过来,用来对服务端的推送做出响应。route
用户可以自定义,格式一般为onXXX
。
pomelo.on(route, cb);
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
例如:
//消息监听
pomelo.on("disconnect", function(msg){
console.log("disconnect", msg);
});