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.
The named import is not supported in some cases:
> node_modules/socket.io-adapter/dist/index.js:170
> packetOpts.wsPreEncodedFrame = ws_1.WebSocket.Sender.frame(data, {
> ^
>
> TypeError: Cannot read properties of undefined (reading 'Sender')
> at RedisAdapter._encode (/.../node_modules/socket.io-adapter/dist/index.js:170:59)
> at RedisAdapter.broadcast (/.../node_modules/socket.io-adapter/dist/index.js:117:37)
Related: https://github.com/socketio/socket.io-redis-adapter/issues/478
Note:
- only packets without binary attachments are affected
- the permessage-deflate extension must be disabled (which is the default)
Previous attempt:
- wsPreEncoded option: 5579d40c24
- fix for binary packets: a33e42bb7b
- revert: 88eee5948a
The binary attachments of volatile packets were discarded (only the
header packet was sent) due to a bug introduced in [1].
Note: the `wsPreEncoded` option is removed by this commit, as I wasn't
able to find an elegant (read: non explosive) way to keep it.
[1]: 5579d40c24
Related: https://github.com/socketio/socket.io/issues/3919
This should fix the related issue:
```
TypeError: Cannot read property 'size' of undefined
at Adapter._del (/app/node_modules/socket.io-adapter/dist/index.js:67:37)
at Adapter.delAll (/app/node_modules/socket.io-adapter/dist/index.js:83:18)
at Socket.leaveAll (/app/node_modules/socket.io/dist/socket.js:190:22)
at Socket._onclose (/app/node_modules/socket.io/dist/socket.js:334:14)
at Client.onclose (/app/node_modules/socket.io/dist/client.js:245:20)
at Socket.emit (events.js:412:35)
at Socket.onClose (/app/node_modules/engine.io/lib/socket.js:348:12)
at Object.onceWrapper (events.js:519:28)
at WebSocket.emit (events.js:400:28)
at WebSocket.onClose (/app/node_modules/engine.io/lib/transport.js:106:10)
```
A test case was added, which reproduces the issue by adding a listener
to the "leave-room" event. This does not seem to be the case for the
user reporting the issue though, which may indicate that the root cause
is elsewhere.
A few notes:
- only the first element is pre-encoded, because the other elements are
buffers and will be sent as is over the WebSocket connection
- using `socket.packet()` was unexpectedly working, we will now use
`socket.client.writeToEngine()` (see [1])
See also: 7706b123df
[1]: https://github.com/socketio/socket.io/issues/3775
This commit adds the following methods:
- fetchSockets: return the matching socket instances
- addSockets: make the matching socket instances join the specified rooms
- delSockets: make the matching socket instances leave the specified rooms
- disconnectSockets: disconnect the matching socket instances
Those methods will then be exposed by the Socket.IO server:
```js
// clear room
io.socketsLeave("room1");
// disconnect all sockets in room
io.in("room2").disconnectSockets();
// fetch socket instances in room
io.in("room3").fetchSockets();
```
This feature will also be extended in the Redis adapter to handle
multiple Socket.IO servers.
These extension points may be used by another adapter, in order to open
or close a connection to a database for example.
In Socket.IO v2, the join() method did accept a callback:
```js
socket.join("room1", () => {
io.to("room1").emit("hello");
});
```
Depending on the adapter, it may now return a promise:
```js
await socket.join("room1");
io.to("room1").emit("hello");
```
Related: https://github.com/socketio/socket.io/issues/3662