UNPKG

omelop

Version:

[![Build Status](https://travis-ci.org/node-omelop/omelop.svg?branch=master)](https://travis-ci.org/node-omelop/omelop)

171 lines 13.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TcpSocket = void 0; const stream_1 = require("stream"); const omelop_protocol_1 = require("omelop-protocol"); const omelop_logger_1 = require("omelop-logger"); const path = require("path"); let logger = (0, omelop_logger_1.getLogger)('omelop', path.basename(__filename)); /** * Work states */ let ST_HEAD = 1; // wait for head let ST_BODY = 2; // wait for body let ST_CLOSED = 3; // closed /** * Tcp socket wrapper with package compositing. * Collect the package from socket and emit a completed package with 'data' event. * Uniform with ws.WebSocket interfaces. * * @param {Object} socket origin socket from node.js net module * @param {Object} opts options parameter. * opts.headSize size of package head * opts.headHandler(headBuffer) handler for package head. caculate and return body size from head data. */ class TcpSocket extends stream_1.Stream { constructor(socket, opts) { // stream style interfaces. // TODO: need to port to stream2 after node 0.9 super(); if (!socket || !opts) { throw new Error('invalid socket or opts'); } if (!opts.headSize || typeof opts.headHandler !== 'function') { throw new Error('invalid opts.headSize or opts.headHandler'); } this.readable = true; this.writeable = true; this._socket = socket; this.headSize = opts.headSize; this.closeMethod = opts.closeMethod; this.headBuffer = Buffer.alloc(opts.headSize); this.headHandler = opts.headHandler; this.headOffset = 0; this.packageOffset = 0; this.packageSize = 0; this.packageBuffer = null; // bind event form the origin socket this._socket.on('data', this.ondata.bind(this)); this._socket.on('end', this.onend.bind(this)); this._socket.on('error', this.emit.bind(this, 'error')); this._socket.on('close', this.emit.bind(this, 'close')); this.state = ST_HEAD; } send(msg, options, cb) { this._socket.write(msg, options.binary ? 'binary' : 'utf8', cb); } close() { if (!!this.closeMethod && this.closeMethod === 'end') { this._socket.end(); } else { try { this._socket.destroy(); } catch (e) { logger.error('socket close with destroy error: %j', e.stack); } } } ondata(chunk) { if (this.state === ST_CLOSED) { throw new Error('socket has closed'); } if (typeof chunk !== 'string' && !Buffer.isBuffer(chunk)) { throw new Error('invalid data'); } if (typeof chunk === 'string') { chunk = Buffer.from(chunk, 'utf8'); } let offset = 0, end = chunk.length; while (offset < end && this.state !== ST_CLOSED) { if (this.state === ST_HEAD) { offset = this.readHead(chunk, offset); } if (this.state === ST_BODY) { offset = this.readBody(chunk, offset); } } return true; } onend(chunk) { if (chunk) { this._socket.write(chunk); } this.state = ST_CLOSED; this.reset(); this.emit('end'); } /** * Read head segment from data to socket.headBuffer. * * @param {Object} socket Socket instance * @param {Object} data Buffer instance * @param {Number} offset offset read star from data * @return {Number} new offset of data after read */ readHead(data, offset) { let hlen = this.headSize - this.headOffset; let dlen = data.length - offset; let len = Math.min(hlen, dlen); let dend = offset + len; data.copy(this.headBuffer, this.headOffset, offset, dend); this.headOffset += len; if (this.headOffset === this.headSize) { // if head segment finished let size = this.headHandler(this.headBuffer); if (size < 0) { throw new Error('invalid body size: ' + size); } // check if header contains a valid type if (checkTypeData(this.headBuffer[0])) { this.packageSize = size + this.headSize; this.packageBuffer = Buffer.alloc(this.packageSize); this.headBuffer.copy(this.packageBuffer, 0, 0, this.headSize); this.packageOffset = this.headSize; this.state = ST_BODY; } else { dend = data.length; logger.error('close the connection with invalid head message, the remote ip is %s && port is %s && message is %j', this._socket.remoteAddress, this._socket.remotePort, data); this.close(); } } return dend; } /** * Read body segment from data buffer to socket.packageBuffer; * * @param {Object} socket Socket instance * @param {Object} data Buffer instance * @param {Number} offset offset read star from data * @return {Number} new offset of data after read */ readBody(data, offset) { let blen = this.packageSize - this.packageOffset; let dlen = data.length - offset; let len = Math.min(blen, dlen); let dend = offset + len; data.copy(this.packageBuffer, this.packageOffset, offset, dend); this.packageOffset += len; if (this.packageOffset === this.packageSize) { // if all the package finished let buffer = this.packageBuffer; this.emit('message', buffer); this.reset(); } return dend; } reset() { this.headOffset = 0; this.packageOffset = 0; this.packageSize = 0; this.packageBuffer = null; this.state = ST_HEAD; } } exports.TcpSocket = TcpSocket; let checkTypeData = function (data) { return data === omelop_protocol_1.Package.TYPE_HANDSHAKE || data === omelop_protocol_1.Package.TYPE_HANDSHAKE_ACK || data === omelop_protocol_1.Package.TYPE_HEARTBEAT || data === omelop_protocol_1.Package.TYPE_DATA || data === omelop_protocol_1.Package.TYPE_KICK; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGNwc29ja2V0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vbGliL2Nvbm5lY3RvcnMvaHlicmlkL3RjcHNvY2tldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBZ0M7QUFHaEMscURBQTBDO0FBQzFDLGlEQUEwQztBQUcxQyw2QkFBNkI7QUFFN0IsSUFBSSxNQUFNLEdBQUcsSUFBQSx5QkFBUyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7QUFTNUQ7O0dBRUc7QUFDSCxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUMsQ0FBTSxnQkFBZ0I7QUFDdEMsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDLENBQU0sZ0JBQWdCO0FBQ3RDLElBQUksU0FBUyxHQUFHLENBQUMsQ0FBQyxDQUFJLFNBQVM7QUFFL0I7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsZUFBTTtJQWdCakMsWUFBWSxNQUFrQixFQUFFLElBQXVCO1FBQ25ELDJCQUEyQjtRQUMzQiwrQ0FBK0M7UUFDL0MsS0FBSyxFQUFFLENBQUM7UUFDUixJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ2xCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLENBQUMsQ0FBQztTQUM3QztRQUVELElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLE9BQU8sSUFBSSxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7WUFDMUQsTUFBTSxJQUFJLEtBQUssQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1NBQ2hFO1FBRUQsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7UUFFdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQzlC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