pinusmod
Version:
[](https://travis-ci.org/node-pinus/pinus)
135 lines (134 loc) • 4.29 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SIOConnector = void 0;
const events_1 = require("events");
const http_1 = require("http");
const https_1 = require("https");
const siosocket_1 = require("./siosocket");
const socket_io_1 = require("socket.io");
let PKG_ID_BYTES = 4;
let PKG_ROUTE_LENGTH_BYTES = 1;
let PKG_HEAD_BYTES = PKG_ID_BYTES + PKG_ROUTE_LENGTH_BYTES;
let curId = 1;
/**
* Connector that manager low level connection and protocol bewteen server and client.
* Develper can provide their own connector to switch the low level prototol, such as tcp or probuf.
*/
class SIOConnector extends events_1.EventEmitter {
constructor(port, host, opts) {
super();
this.port = port;
this.host = host;
this.opts = opts;
opts.pingTimeout = opts.pingTimeout || 60;
opts.pingInterval = opts.pingInterval || 25;
this.sshKey = opts.sshKey;
this.sshCert = opts.sshCert;
}
/**
* Start connector to listen the specified port
*/
start(cb) {
let self = this;
// issue https://github.com/NetEase/pinus-cn/issues/174
let opts;
if (!!this.opts) {
opts = this.opts;
}
else {
opts = {
transports: [
'websocket', 'polling-xhr', 'polling-jsonp', 'polling'
]
};
}
opts.path = '/socket.io';
let port = this.port;
let sio;
if (!!this.sshKey) {
let httpsServer = (0, https_1.createServer)({ key: self.sshKey, cert: self.sshCert }, function (req, res) {
// 要是单纯的https连接的话就会返回这个东西
console.log('sio https Server listening at port %d', port);
res.writeHead(200);
res.end('HTTPS Server is up');
}).listen(port);
sio = new socket_io_1.Server(httpsServer, opts);
}
else {
let httpServer = (0, http_1.createServer)();
sio = new socket_io_1.Server(httpServer, opts);
httpServer.listen(port, function () {
console.log('sio http Server listening at port %d', port);
});
}
sio.on('connection', (socket) => {
// this.wsocket.sockets.on('connection', function (socket) {
let siosocket = new siosocket_1.SioSocket(curId++, socket);
self.emit('connection', siosocket);
siosocket.on('closing', function (reason) {
siosocket.send({ route: 'onKick', reason: reason });
});
});
process.nextTick(cb);
}
/**
* Stop connector
*/
stop(force, cb) {
this.server.close();
process.nextTick(cb);
}
encode(reqId, route, msg) {
if (reqId) {
return composeResponse(reqId, route, msg);
}
else {
return composePush(route, msg);
}
}
/**
* Decode client message package.
*
* Package format:
* message id: 4bytes big-endian integer
* route length: 1byte
* route: route length bytes
* body: the rest bytes
*
* @param {String} data socket.io package from client
* @return {Object} message object
*/
decode(msg) {
let index = 0;
let id = parseIntField(msg, index, PKG_ID_BYTES);
index += PKG_ID_BYTES;
let routeLen = parseIntField(msg, index, PKG_ROUTE_LENGTH_BYTES);
let route = msg.substr(PKG_HEAD_BYTES, routeLen);
let body = msg.substr(PKG_HEAD_BYTES + routeLen);
return {
id: id,
route: route,
body: JSON.parse(body)
};
}
}
exports.SIOConnector = SIOConnector;
let composeResponse = function (msgId, route, msgBody) {
return {
id: msgId,
body: msgBody
};
};
let composePush = function (route, msgBody) {
return JSON.stringify({ route: route, body: msgBody });
};
let parseIntField = function (str, offset, len) {
let res = 0;
for (let i = 0; i < len; i++) {
if (i > 0) {
res <<= 8;
}
res |= str.charCodeAt(offset + i) & 0xff;
}
return res;
};