lipp/node-jet

View on GitHub
src/1_socket/wsserver.ts

Summary

Maintainability
A
1 hr
Test Coverage
/* istanbul ignore file */
import { EventEmitter, WebSocketImpl } from './index.js'
import { WebSocket, WebSocketServer as WsServer } from 'ws'
import { Server as HTTPServer } from 'http'
import { Socket } from './socket.js'

export interface WebServerConfig {
  url?: string
  wsPort?: number
  wsPath?: string
  server?: HTTPServer
  wsPingInterval?: number
}

/**
 * Class implementation of a WS server. This implementation only runs in a node.js environment
 */
export class WebsocketServer extends EventEmitter {
  config: WebServerConfig
  wsServer!: WsServer
  connectionId = 1
  constructor(config: WebServerConfig) {
    super()
    this.config = config
  }
  /**
   * method to start listening on incoming websocket connections. Incoming websocket connections are validated if they accept jet protocol
   */
  listen() {
    this.wsServer = new WsServer({
      port: this.config.wsPort,
      server: this.config.server,
      path: this.config.wsPath,
      handleProtocols: (protocols: Set<string>) => {
        if (protocols.has('jet')) {
          return 'jet'
        } else {
          return false
        }
      }
    })
    this.wsServer.on('connection', (ws: WebSocket) => {
      const sock = new Socket(ws)
      sock.id = `ws_${this.connectionId}`
      this.connectionId++
      const pingMs = this.config.wsPingInterval || 5000
      let pingInterval: NodeJS.Timeout
      if (pingMs) {
        pingInterval = setInterval(() => {
          if (ws.readyState === WebSocketImpl.OPEN) {
            ws.ping()
          }
        }, pingMs)
      }
      ws.addListener('close', () => {
        clearInterval(pingInterval)
        this.emit('disconnect', sock)
      })
      ws.addListener('disconnect', () => {
        this.emit('disconnect', sock)
      })

      this.emit('connection', sock)
    })
  }
  /** Method to stop Websocket server */
  close() {
    this.wsServer.close()
  }
}