UNPKG

@sex-pomelo/sex-pomelo

Version:

[![NPM version][npm-image-pomelo]][npm-url-pomelo] [![NPM version][npm-image-down]][npm-url-pomelo]

85 lines (68 loc) 1.93 kB
"use strict"; const HttpServer = require('http').Server; const EventEmitter = require('events').EventEmitter; const WebSocketServer = require('ws').Server; const ST_STARTED = 1; const ST_CLOSED = 2; /** * websocket protocol processor * @class * @memberof hybridConnector */ class Processor extends EventEmitter { constructor() { super(); this.httpServer = new HttpServer(); let self = this; this.wsServer = new WebSocketServer({server: this.httpServer}); this.wsServer.on('connection', function(socket) { // emit socket to outside self.emit('connection', socket); }); this.state = ST_STARTED; } add (socket, data) { if(this.state !== ST_STARTED) { return; } this.httpServer.emit('connection', socket); // Get client real IP through X-Forwarded-For,Take only one if( socket.pomeloIPAddarr !== true){ socket.pomeloIPAddarr = true; const headers = data.toString().split('\r\n'); const len = headers.length; for( let i = 0;i <len;i++ ){ const it = headers[i]; if( it.length > 19 ){ if(it.substring(0,15).toLowerCase() === 'x-forwarded-for') { const ip = it.substring(16); socket.pomeloXffIP = ip.trim(); break; } } } } if(typeof socket.ondata === 'function') { // compatible with stream2 socket.ondata(data, 0, data.length); } else { // compatible with old stream socket.emit('data', data); } } close() { if(this.state !== ST_STARTED) { return; } this.state = ST_CLOSED; this.wsServer.close(); for (const ws of this.wsServer.clients) { ws.terminate(); } this.wsServer = null; this.httpServer = null; } } module.exports = Processor;