Exit Full View

Games Cupboard / build / js / node_modules / webpack-dev-server / lib / servers / WebsocketServer.js

'use strict';

/* eslint-disable
  class-methods-use-this
*/
const WebSocket = require('ws');
const BaseServer = require('./BaseServer');

module.exports = class WebsocketServer extends BaseServer {
  static heartbeatInterval = 1000;

  constructor(server) {
    super(server);

    const options = {
      ...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);

    this.server.server.on('upgrade', (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', (err) => {
      this.server.logger.error(err.message);
    });

    const interval = setInterval(() => {
      this.clients.forEach((client) => {
        if (client.isAlive === false) {
          client.terminate();

          return;
        }

        client.isAlive = false;
        client.ping(() => {});
      });
    }, WebsocketServer.heartbeatInterval);

    this.implementation.on('connection', (client) => {
      this.clients.add(client);

      client.isAlive = true;

      client.on('pong', () => {
        client.isAlive = true;
      });

      client.on('close', () => {
        this.clients.delete(client);
      });
    });

    this.implementation.on('close', () => {
      clearInterval(interval);

      this.clients.clear();
    });
  }
};