You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
"use strict";
const WebSocket = require("ws"); const BaseServer = require("./BaseServer");
/** @typedef {import("../Server").WebSocketServerConfiguration} WebSocketServerConfiguration */ /** @typedef {import("../Server").ClientConnection} ClientConnection */
module.exports = class WebsocketServer extends BaseServer { static heartbeatInterval = 1000;
/** * @param {import("../Server")} server */ constructor(server) { super(server);
/** @type {import("ws").ServerOptions} */ const options = { .../** @type {WebSocketServerConfiguration} */ (this.server.options.webSocketServer).options, clientTracking: false, }; const isNoServerMode = typeof options.port === "undefined" && typeof options.server === "undefined";
if (isNoServerMode) { options.noServer = true; }
this.implementation = new WebSocket.Server(options);
/** @type {import("http").Server} */ (this.server.server).on( "upgrade", /** * @param {import("http").IncomingMessage} req * @param {import("stream").Duplex} sock * @param {Buffer} head */ (req, sock, head) => { if (!this.implementation.shouldHandle(req)) { return; }
this.implementation.handleUpgrade(req, sock, head, (connection) => { this.implementation.emit("connection", connection, req); }); } );
this.implementation.on( "error", /** * @param {Error} err */ (err) => { this.server.logger.error(err.message); } );
const interval = setInterval(() => { this.clients.forEach( /** * @param {ClientConnection} client */ (client) => { if (client.isAlive === false) { client.terminate();
return; }
client.isAlive = false; client.ping(() => {}); } ); }, WebsocketServer.heartbeatInterval);
this.implementation.on( "connection", /** * @param {ClientConnection} client */ (client) => { this.clients.push(client);
client.isAlive = true;
client.on("pong", () => { client.isAlive = true; });
client.on("close", () => { this.clients.splice(this.clients.indexOf(client), 1); }); } );
this.implementation.on("close", () => { clearInterval(interval); }); } };
|