UNPKG

it-ws

Version:

Simple async iterables for websocket client connections

88 lines 2.83 kB
import { EventEmitter } from 'events'; import http from 'http'; import https from 'https'; import { WebSocketServer as WSServer } from 'ws'; import duplex, {} from './duplex.js'; class Server extends EventEmitter { server; wsServer; constructor(server, opts) { super(); opts = opts ?? {}; this.server = server; this.wsServer = new WSServer({ server, perMessageDeflate: false, verifyClient: opts.verifyClient }); this.wsServer.on('connection', this.onWsServerConnection.bind(this)); } async listen(addrInfo) { return new Promise((resolve, reject) => { this.wsServer.once('error', (e) => { reject(e); }); this.wsServer.once('listening', () => { resolve(this); }); this.server.listen(typeof addrInfo === 'number' ? addrInfo : addrInfo.port); }); } async close() { await new Promise((resolve, reject) => { this.server.close((err) => { if (err != null) { reject(err); return; } resolve(); }); }); } address() { return this.server.address(); } onWsServerConnection(socket, req) { let addr; try { if (req.socket.remoteAddress == null || req.socket.remotePort == null) { throw new Error('Remote connection did not have address and/or port'); } addr = this.wsServer.address(); if (typeof addr === 'string') { throw new Error('Cannot listen on unix sockets'); } if (addr == null) { throw new Error('Server was closing or not running'); } } catch (err) { req.destroy(err); this.emit('error', err); return; } const stream = { ...duplex(socket, { remoteAddress: req.socket.remoteAddress, remotePort: req.socket.remotePort }), localAddress: addr.address, localPort: addr.port }; this.emit('connection', stream, req); } } export function createServer(opts) { opts = opts ?? {}; const server = opts.server ?? (opts.key != null && opts.cert != null ? https.createServer(opts) : http.createServer()); const wss = new Server(server); if (opts.onConnection != null) { wss.on('connection', opts.onConnection); } function proxy(server, event) { return server.on(event, (...args) => { wss.emit(event, ...args); }); } proxy(server, 'listening'); proxy(server, 'request'); proxy(server, 'close'); return wss; } //# sourceMappingURL=server.js.map