Previously, getting disconnected while waiting for an acknowledgement
would create a memory leak, as the acknowledgement was never received
and the handler would stay in memory forever.
This commit fixes the issue:
- handlers that do accept an error as first argument, such as:
* `socket.emit("test", (err, value) => { ... })` with `ackTimeout` option
* `socket.timeout(5000).emit("test", (err, value) => { ... })`
* `const value = await socket.emitWithAck("test")`
will now properly resolve with an error and get discarded.
- handlers that don't like `socket.emit("test", (value) => { ... });`
will simply be discarded upon disconnection
Note: the structure of the 'acks' attribute has been left untouched, in
order to prevent any breaking change.
Related:
- https://github.com/socketio/socket.io-client/issues/1546
- https://github.com/socketio/socket.io/issues/4964
Before this change, the broadcast() method would send the BROADCAST
command and then apply it locally (which is required to retrieve the
offset of the message, when connection state recovery is enabled),
while the other commands like disconnectSockets() would first apply it
locally and then send the command to the other nodes.
So, for example:
```js
io.emit("bye");
io.disconnectSockets();
```
In that case, the clients connected to the io instance would not receive
the "bye" event, while the clients connected to the other server
instances would receive it before being disconnected.
Related:
- https://github.com/socketio/socket.io-redis-streams-adapter/issues/13
- https://github.com/socketio/socket.io-postgres-adapter/issues/12
Note: the current API does not currently allow the user to handle those
errors (and retry, for example). This might be worth investigating for
the next major version, maybe something like:
```js
try {
await io.emit("hello");
} catch (e) {
// something went wrong
}
```
Related: https://github.com/socketio/socket.io-mongo-adapter/issues/15
The Redis adapter is currently the only adapter which makes a
distinction between publishing messages (one channel for all) and
responses (one channel for each node).
The clustered adapter will now:
- periodically check if a node has left the cluster
- send an event when it leaves the cluster
This should reduce the number of "timeout reached: only x responses
received out of y" errors.
Imported from ef5f0da0b4/lib/cluster-adapter.ts
This abstract class is currently used by the sharded Redis adapter. We
import it here because the logic can be reused by the other adapters,
which will then only need to handle the pub/sub mechanism.
When compiling with TypeScript with module set to "node16" and
moduleResolution to "node16", the following error would be thrown:
> node_modules/engine.io-parser/build/cjs/index.d.ts:6:54 - error TS2304: Cannot find name 'TransformStream'.
> 6 export declare function createPacketEncoderStream(): TransformStream<Packet, any>;
> ~~~~~~~~~~~~~~~
> node_modules/engine.io-parser/build/cjs/index.d.ts:7:96 - error TS2304: Cannot find name 'TransformStream'.
> 7 export declare function createPacketDecoderStream(maxPayload: number, binaryType: BinaryType): TransformStream<Uint8Array, any>;
> ~~~~~~~~~~~~~~~
> Found 2 errors in the same file, starting at: node_modules/engine.io-parser/build/cjs/index.d.ts:6
This is because the TransformStream object is not exposed in the global
scope in the `@types/node` package, even though it is since Node.js
`v18.0.0`.
Reference: https://nodejs.org/api/webstreams.html#class-transformstream
Note: we only import the TransformStream type (not value) because it
isn't defined on older Node.js versions.
Related:
- https://github.com/socketio/engine.io-parser/issues/136
- https://github.com/socketio/socket.io-client/issues/1606