The "drain" event (added in [1]) had two different meanings:
- the transport is ready to be written
- the packets are sent over the wire
For the WebSocket and the WebTransport transports, those two events
happen at the same time, but this is not the case for the HTTP
long-polling transport:
- the transport is ready to be written when the client sends a GET request
- the packets are sent over the wire when the server responds to the GET request
Which caused an issue with send callbacks during an upgrade, since the
packets were written but the client would not open a new GET request.
There are now two distinct events: "ready" and "drain"
Related: https://github.com/socketio/engine.io/issues/695
[1]: 2a93f06e27
This behavior was added in [1]. However, there are two problems:
- a new timer is allocated every time a packet is received, which is
wasteful
- the next heartbeat is not actually delayed, since it's the timeout
timer which gets reset, and not the interval timer
Note: delaying the next heartbeat would be a breaking change.
[1]: be7b4e7478
Instead of allocating one temporary function for each WebSocket
`send()` call.
Regarding the test removal, the permessage-deflate threshold was
implemented in the "ws" package in [1], so it's not needed anymore.
[1]: 6b3904b42d
The wsPreEncoded option was added in the `socket.io-adapter` package
when broadcasting a message to multiple clients.
It was removed in [1] and is now superseded by the `wsPreEncodedFrame`
option, which directly computes the WebSocket frame once for all
clients (see [2]).
[1]: 88eee5948a
[2]: 5f7b47d40f
With the `websocket` transport, the callbacks which indicate that the
packets are actually written were not properly called.
Example:
```js
socket.send("hello", () => {
// the message has been written to the underlying transport
});
```
The bug was caused by the `websocket` transport (and `webtransport` as
well) having its `supportsFraming` property set to `true`, despite
having been changed in [1] to emit a single `drain` event for each
batch of messages written to the transport like the `polling` transport
always did. Note that although [1] is partially reverted in [2], the
new `drain` event behavior is preserved as called out in that commit's
message.
The `supportsFraming` attribute was introduced in [3] (amended by [4])
as a way to distinguish transports that emit one `drain` per message
from those that emit one `drain` per batch. Since the delivery of
`send` callbacks depends on matching `drain` events with
`transport.send` calls, that distinction is vital to correct behavior.
However, now that all transports have converged to "one `drain` per
batch" behavior, this `supportsFraming` property can be retired (and
the code for calling callbacks simplified).
[1]: https://github.com/socketio/engine.io/pull/618
[2]: a65a047526
[3]: https://github.com/socketio/engine.io/pull/130
[4]: https://github.com/socketio/engine.io/pull/132
Related: https://github.com/socketio/engine.io/issues/698
The yeast() method could generate the same string twice when used in
two different iframes, which can cause Safari to only send one HTTP
request (deduplication) and trigger an HTTP 400 error afterwards since
the two iframes share the same session ID.
This new method, combining 5 chars from the timestamp and 3 chars from
Math.random() should be sufficient for our use case.
Related: https://github.com/socketio/engine.io/issues/690
See also: 874484cc1e
The debug package was not included anymore in the dev bundle since the
migration from webpack to rollup ([1]) in version 6.0.0.
[1]: 27de300de4
See also: 4683a954d4