1 Star 0 Fork 2

无心/pomelo-cocos2dx-js

forked from codin/pomelo-cocos2dx-js 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
Pomelo.js 8.16 KB
一键复制 编辑 原始数据 按行查看 历史
codin 提交于 2014-04-09 17:50 . upate
const JS_WS_CLIENT_TYPE = 'js-websocket';
const JS_WS_CLIENT_VERSION = '0.0.1';
const RES_OK = 200;
const RES_FAIL = 500;
const RES_OLD_CLIENT = 501;
var Pomelo = Emitter.extend({
ctor: function(){
this._super();
this.socket = null;
this.reqId = 0;
this.reqCallbacks = {};
//Map from request id to route
this.routeMap = {};
this.heartbeatInterval = 0;
this.heartbeatTimeout = 0;
this.nextHeartbeatTimeout = 0;
this.gapThreshold = 100; // heartbeat gap threashold
this.heartbeatId = null;
this.heartbeatTimeoutId = null;
this.handshakeCallback = null;
this.handshakeBuffer = {
'sys': {
type: JS_WS_CLIENT_TYPE,
version: JS_WS_CLIENT_VERSION
},
'user': {}
};
this.initCallback = null;
this.lastReqTime = 0;
this.reqGap = 300; // 访问间隔,太频繁则不发送访问
},
init: function(params,cb) {
this.initCallback = cb;
var host = params.host;
var port = params.port;
var url = 'ws://' + host;
if (port) {
url += ':' + port;
}
this.initWebSocket(url);
},
initWebSocket: function(url) {
var self = this;
var onopen = function(event) {
cc.log("onopen");
var obj = Package.encode(Package.TYPE_HANDSHAKE,Protocol.strencode(JSON.stringify(self.handshakeBuffer)));
self.send(obj);
};
var onmessage = function(event) {
cc.log("onmessage");
self.processPackage(Package.decode(event.data));
// new package arrived,update the heartbeat timeout
if (self.heartbeatTimeout) {
self.nextHeartbeatTimeout = Date.now() + self.heartbeatTimeout;
}
};
var onerror = function(event) {
self.emit('io-error',event);
cc.error('socket error: ',event);
};
var onclose = function(event) {
cc.log("onclose");
self.emit('close',event);
};
this.socket = new WebSocket(url);
this.socket.binaryType = 'arraybuffer';
this.socket.onopen = onopen;
this.socket.onmessage = onmessage;
this.socket.onerror = onerror;
this.socket.onclose = onclose;
},
isReady:function(){
return this.socket && this.socket.readyState === WebSocket.OPEN;
},
disconnect: function() {
if (this.isReady()) {
this.socket.close();
this.socket = null;
}
if (this.heartbeatId) {
clearTimeout(this.heartbeatId);
this.heartbeatId = null;
}
if (this.heartbeatTimeoutId) {
clearTimeout(this.heartbeatTimeoutId);
this.heartbeatTimeoutId = null;
}
},
request: function(route,msg,cb,ignoreGap) {
if(!this.isReady()){
cc.error("socket is not ready!");
return;
}
var now = Date.now();
if(!ignoreGap && this.lastReqTime !==0 && (now-this.lastReqTime<this.reqGap)){
cc.error("request too frequently!");
return;
}
this.lastReqTime = now;
if (arguments.length === 2 && typeof msg === 'function') {
cb = msg;
msg = {};
} else {
msg = msg || {};
}
route = route || msg.route;
if (!route) {
return;
}
this.reqId++;
this.sendMessage(this.reqId,route,msg);
this.reqCallbacks[this.reqId] = cb;
this.routeMap[this.reqId] = route;
},
notify: function(route,msg) {
msg = msg || {},
this.sendMessage(0,route,msg);
},
sendMessage: function(reqId,route,msg) {
var type = reqId ? Message.TYPE_REQUEST: Message.TYPE_NOTIFY;
msg = Protocol.strencode(JSON.stringify(msg));
var compressRoute = 0;
msg = Message.encode(reqId,type,compressRoute,route,msg);
var packet = Package.encode(Package.TYPE_DATA,msg);
this.send(packet);
},
send: function(packet) {
if(!this.isReady()){
cc.error("socket is not ready!");
return;
}
this.socket.send(packet.buffer);
},
heartbeat: function(data) {
if (!this.heartbeatInterval) {
// no heartbeat
return;
}
var obj = Package.encode(Package.TYPE_HEARTBEAT);
if (this.heartbeatTimeoutId) {
clearTimeout(this.heartbeatTimeoutId);
this.heartbeatTimeoutId = null;
}
if (this.heartbeatId) {
// already in a heartbeat interval
return;
}
var self = this;
this.heartbeatId = (
function() {
self.heartbeatId = null;
self.send(obj);
self.nextHeartbeatTimeout = Date.now() + self.heartbeatTimeout;
self.heartbeatTimeoutId = setTimeout(self.heartbeatTimeoutCb,self.heartbeatTimeout);
},self.heartbeatInterval);
},
heartbeatTimeoutCb: function() {
var gap = this.nextHeartbeatTimeout - Date.now();
if (gap > this.gapThreshold) {
this.heartbeatTimeoutId = setTimeout(this.heartbeatTimeoutCb,gap);
} else {
this.emit('heartbeat timeout');
this.disconnect();
}
},
handshake: function(data) {
data = JSON.parse(Protocol.strdecode(data));
if (data.code === RES_OLD_CLIENT) {
this.emit('error','client version not fullfill');
return;
}
if (data.code !== RES_OK) {
this.emit('error','handshake fail');
return;
}
this.handshakeInit(data);
var obj = Package.encode(Package.TYPE_HANDSHAKE_ACK);
this.send(obj);
if (this.initCallback) {
this.initCallback(this.socket);
this.initCallback = null;
}
},
onData: function(data) {
//probuff decode
var msg = Message.decode(data);
if (msg.id > 0) {
msg.route = this.routeMap[msg.id];
delete this.routeMap[msg.id];
if (!msg.route) {
return;
}
}
msg.body = this.deCompose(msg);
this.processMessage(msg);
},
onKick: function(data) {
this.emit('onKick');
},
processPackage: function(msg) {
switch(msg.type){
case Package.TYPE_HANDSHAKE:
this.handshake(msg.body);
break;
case Package.TYPE_HEARTBEAT:
this.heartbeat(msg.body);
break;
case Package.TYPE_DATA:
this.onData(msg.body);
break;
case Package.TYPE_KICK:
this.onKick(msg.body);
break;
default :
cc.error("unknown package type!");
break;
}
},
processMessage: function(msg) {
if (!msg.id) {
// server push message
this.emit(msg.route,msg.body);
}
//if have a id then find the callback function with the request
var cb = this.reqCallbacks[msg.id];
delete this.reqCallbacks[msg.id];
if (typeof cb !== 'function') {
return;
}
cb(msg.body);
return;
},
processMessageBatch: function(msgs) {
for (var i = 0,l = msgs.length; i < l; i++) {
this.processMessage(msgs[i]);
}
},
deCompose: function(msg) {
return JSON.parse(Protocol.strdecode(msg.body));
},
handshakeInit: function(data) {
if (data.sys && data.sys.heartbeat) {
this.heartbeatInterval = data.sys.heartbeat * 1000; // heartbeat interval
this.heartbeatTimeout = this.heartbeatInterval * 2; // max heartbeat timeout
} else {
this.heartbeatInterval = 0;
this.heartbeatTimeout = 0;
}
if (typeof this.handshakeCallback === 'function') {
this.handshakeCallback(data.user);
}
}
});
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
JavaScript
1
https://gitee.com/fawuxin/pomelo-cocos2dx-js.git
git@gitee.com:fawuxin/pomelo-cocos2dx-js.git
fawuxin
pomelo-cocos2dx-js
pomelo-cocos2dx-js
master

搜索帮助