@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
JavaScript
"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