pinusmod
Version:
[](https://travis-ci.org/node-pinus/pinus)
139 lines (138 loc) • 3.98 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.HybridSocket = void 0;
const pinusmod_protocol_1 = require("pinusmod-protocol");
const pinusmod_logger_1 = require("pinusmod-logger");
const events_1 = require("events");
const handler_1 = require("./common/handler");
const path = require("path");
let logger = (0, pinusmod_logger_1.getLogger)('pinus', path.basename(__filename));
let ST_INITED = 0;
let ST_WAIT_ACK = 1;
let ST_WORKING = 2;
let ST_CLOSED = 3;
/**
* Socket class that wraps socket and websocket to provide unified interface for up level.
*/
class HybridSocket extends events_1.EventEmitter {
constructor(id, socket, request, opts) {
super();
this.id = id;
this.socket = socket;
if (request && (opts.realIPKey || opts.realPortKey)) {
let ip = request['headers'][opts.realIPKey];
if (ip) {
this.remoteAddress = {
ip: ip,
port: opts.realPortKey ? request['headers'][opts.realPortKey] : 0
};
}
}
if (!this.remoteAddress) {
if (!socket._socket) {
this.remoteAddress = {
ip: socket.address().address,
port: socket.address().port
};
}
else {
this.remoteAddress = {
ip: socket._socket.remoteAddress,
port: socket._socket.remotePort
};
}
}
let self = this;
socket.once('close', this.emit.bind(this, 'disconnect'));
socket.on('error', this.emit.bind(this, 'error'));
socket.on('message', function (msg) {
if (msg) {
msg = pinusmod_protocol_1.Package.decode(msg);
(0, handler_1.default)(self, msg);
}
});
this.state = ST_INITED;
// TODO: any other events?
}
/**
* Send raw byte data.
*
* @api private
*/
sendRaw(msg) {
if (this.state !== ST_WORKING) {
return;
}
let self = this;
this.socket.send(msg, 'binary', (err) => {
if (!!err) {
logger.error('websocket send binary data failed: %j', err.stack);
return;
}
});
}
/**
* Send byte data package to client.
*
* @param {Buffer} msg byte data
*/
send(msg) {
if (msg instanceof String) {
msg = Buffer.from(msg);
}
else if (!(msg instanceof Buffer)) {
msg = Buffer.from(JSON.stringify(msg));
}
this.sendRaw(pinusmod_protocol_1.Package.encode(pinusmod_protocol_1.Package.TYPE_DATA, msg));
}
/**
* Send byte data packages to client in batch.
*
* @param {Buffer} msgs byte data
*/
sendBatch(msgs) {
let rs = [];
for (let i = 0; i < msgs.length; i++) {
let src = pinusmod_protocol_1.Package.encode(pinusmod_protocol_1.Package.TYPE_DATA, msgs[i]);
rs.push(src);
}
this.sendRaw(Buffer.concat(rs));
}
/**
* Send message to client no matter whether handshake.
*
* @api private
*/
sendForce(msg) {
if (this.state === ST_CLOSED) {
return;
}
this.socket.send(msg, 'binary');
}
/**
* Response handshake request
*
* @api private
*/
handshakeResponse(resp) {
if (this.state !== ST_INITED) {
return;
}
this.socket.send(resp, 'binary');
this.state = ST_WAIT_ACK;
}
/**
* Close the connection.
*
* @api private
*/
disconnect() {
if (this.state === ST_CLOSED) {
return;
}
this.state = ST_CLOSED;
this.socket.emit('close');
this.socket.close();
}
}
exports.HybridSocket = HybridSocket;