it-ws
Version:
Simple async iterables for websocket client connections
88 lines • 2.83 kB
JavaScript
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