fcs
2025-04-10 0163870d662dc5b7d69ceff977490ede594f7d82
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
const Transport = require("../transport");
const debug = require("debug")("engine:ws");
 
class WebSocket extends Transport {
  /**
   * WebSocket transport
   *
   * @param {http.IncomingMessage}
   * @api public
   */
  constructor(req) {
    super(req);
    this.socket = req.websocket;
    this.socket.on("message", this.onData.bind(this));
    this.socket.once("close", this.onClose.bind(this));
    this.socket.on("error", this.onError.bind(this));
    this.writable = true;
    this.perMessageDeflate = null;
  }
 
  /**
   * Transport name
   *
   * @api public
   */
  get name() {
    return "websocket";
  }
 
  /**
   * Advertise upgrade support.
   *
   * @api public
   */
  get handlesUpgrades() {
    return true;
  }
 
  /**
   * Advertise framing support.
   *
   * @api public
   */
  get supportsFraming() {
    return true;
  }
 
  /**
   * Processes the incoming data.
   *
   * @param {String} encoded packet
   * @api private
   */
  onData(data) {
    debug('received "%s"', data);
    super.onData(data);
  }
 
  /**
   * Writes a packet payload.
   *
   * @param {Array} packets
   * @api private
   */
  send(packets) {
    const packet = packets.shift();
    if (typeof packet === "undefined") {
      this.writable = true;
      this.emit("drain");
      return;
    }
 
    // always creates a new object since ws modifies it
    const opts = {};
    if (packet.options) {
      opts.compress = packet.options.compress;
    }
 
    const send = data => {
      if (this.perMessageDeflate) {
        const len =
          "string" === typeof data ? Buffer.byteLength(data) : data.length;
        if (len < this.perMessageDeflate.threshold) {
          opts.compress = false;
        }
      }
      debug('writing "%s"', data);
      this.writable = false;
 
      this.socket.send(data, opts, err => {
        if (err) return this.onError("write error", err.stack);
        this.send(packets);
      });
    };
 
    if (packet.options && typeof packet.options.wsPreEncoded === "string") {
      send(packet.options.wsPreEncoded);
    } else {
      this.parser.encodePacket(packet, this.supportsBinary, send);
    }
  }
 
  /**
   * Closes the transport.
   *
   * @api private
   */
  doClose(fn) {
    debug("closing");
    this.socket.close();
    fn && fn();
  }
}
 
module.exports = WebSocket;