UNPKG

@hapiness/core

Version:

Project to have a HapiJS (https://hapijs.com/) based framework to create easier NodeJS back-end with some awesome features

160 lines 4.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const _1 = require("../../"); const Rx_1 = require("rxjs/Rx"); const websocket_1 = require("websocket"); const socket_1 = require("./socket"); const http = require("http"); const https = require("https"); const rooms_1 = require("./rooms"); class WebSocketServer { constructor(config) { this.config = config; this.connections$ = new Rx_1.Subject(); this.secure = () => Rx_1.Observable.of(true); } start() { this.httpServer = !!this.config.useHttpExtension ? this.getHttpServerExt() : this.createHttpServer(); const _config = Object.assign({ httpServer: this.httpServer }, this.config, { port: undefined }); this.server = new websocket_1.server(_config); this.sockets = []; this.server.on('request', _request => { this .secure(_request) .subscribe(_ => !!_ ? this.onRequestHandler(_request) : _request.reject(403, 'Forbidden')); }); this.rooms = new rooms_1.WebSocketRooms(); } /** * Close all sockets and close http server * * @returns Observable */ stop() { return Rx_1.Observable .from([].concat(this.getSockets()).filter(_ => !!_)) .do(_ => _.close()) .toArray() .flatMap(_ => Rx_1.Observable .create(obs => { if (!this.config.useHttpExtension) { this.httpServer.close(() => { obs.next(); obs.complete(); }); } else { obs.next(); obs.complete(); } })) .map(_ => true); } /** * Get Http Server Extension instance * @FIXME Just take the first HapiJS connection for now */ getHttpServerExt() { const ext = _1.Hapiness['extensions'].find(_ => _.token === _1.HttpServerExt); if (!!ext) { return ext.value.connections[0].listener; } else { throw new Error('Could not find Http Server Extension'); } } /** * Create Http Server for websocket * * @returns http */ createHttpServer() { if (!this.config.port) { throw new Error('WS port not provided'); } /* istanbul ignore next */ const httpHandler = (_request, _response) => { _response.writeHead(404); _response.end(); }; const httpServer = !!this.config.tls ? https.createServer(this.config.tls, httpHandler) : http.createServer(httpHandler); httpServer.listen(this.config.port); return httpServer; } /** * Resquest handler * Accept the request * * @param {request} _request */ onRequestHandler(_request) { const connection = _request.accept(_request.httpRequest.headers['sec-websocket-protocol'] || '', _request.origin); const socket = new socket_1.Socket(_request, connection, this.rooms); const index = this.sockets.push(socket) - 1; connection.on('close', conn => { this.sockets.splice(index, 1); }); this.connections$.next(socket); } /** * Configure a secure callback * to accept/reject requests * * @param {(request:request)=>Observable<boolean>} secure * @returns Subject */ configure(secure) { this.secure = (!!secure ? secure : this.secure); return this.connections$; } /** * Get connections Subject * * @returns Subject */ connections() { return this.connections$; } /** * Get active sockets * * @returns Socket */ getSockets() { return this.sockets; } /** * Broadcast data into active sockets * * @param {string} event * @param {any} data */ broadcast(event, data) { this.server.broadcastUTF(JSON.stringify({ event, data })); } /** * Send a message to all sockets present in a room * * @param {string} room * @param {string} event * @param {any} data * @returns WebSocketServer */ to(room, event, data) { this.rooms.emit(room, event, data); return this; } getServer() { return this.server; } getHttpServer() { return this.httpServer; } } exports.WebSocketServer = WebSocketServer; //# sourceMappingURL=server.js.map