Skip to content

Commit 5cfdf90

Browse files
docs: add details about the implementation
1 parent 4dae265 commit 5cfdf90

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- [ES6 module](#es6-modules)
1111
- [TypeScript](#typescript)
1212
- [Compatibility table](#compatibility-table)
13+
- [How does it work under the hood?](#how-does-it-work-under-the-hood)
1314
- [API](#api)
1415
- [adapter(uri[, opts])](#adapteruri-opts)
1516
- [adapter(opts)](#adapteropts)
@@ -78,7 +79,7 @@ io.on('connection', (socket) => {
7879
});
7980
```
8081

81-
will properly be broadcast to the clients through the Redis Pub/Sub mechanism.
82+
will properly be broadcast to the clients through the Redis [Pub/Sub mechanism](https://redis.io/topics/pubsub).
8283

8384
If you need to emit events to socket.io instances from a non-socket.io
8485
process, you should use [socket.io-emitter](https://github.com/socketio/socket.io-emitter).
@@ -91,6 +92,61 @@ process, you should use [socket.io-emitter](https://github.com/socketio/socket.i
9192
| 5.x | 2.x |
9293
| 6.x | 3.x |
9394

95+
## How does it work under the hood?
96+
97+
This adapter extends the [in-memory adapter](https://github.com/socketio/socket.io-adapter/) that is included by default with the Socket.IO server.
98+
99+
The in-memory adapter stores the relationships between Sockets and Rooms in two Maps.
100+
101+
When you run `socket.join("room21")`, here's what happens:
102+
103+
```
104+
console.log(adapter.rooms); // Map { "room21" => Set { "mdpk4kxF5CmhwfCdAHD8" } }
105+
console.log(adapter.sids); // Map { "mdpk4kxF5CmhwfCdAHD8" => Set { "mdpk4kxF5CmhwfCdAHD8", room21" } }
106+
// "mdpk4kxF5CmhwfCdAHD8" being the ID of the given socket
107+
```
108+
109+
Those two Maps are then used when broadcasting:
110+
111+
- a broadcast to all sockets (`io.emit()`) loops through the `sids` Map, and send the packet to all sockets
112+
- a broadcast to a given room (`io.to("room21").emit()`) loops through the Set in the `rooms` Map, and sends the packet to all matching sockets
113+
114+
The Redis adapter extends the broadcast function of the in-memory adapter: the packet is also [published](https://redis.io/topics/pubsub) to a Redis channel (see [below](#protocol) for the format of the channel name).
115+
116+
Each Socket.IO server receives this packet and broadcasts it to its own list of connected sockets.
117+
118+
To check what's happening on your Redis instance:
119+
120+
```
121+
$ redis-cli
122+
127.0.0.1:6379> PSUBSCRIBE *
123+
Reading messages... (press Ctrl-C to quit)
124+
1) "psubscribe"
125+
2) "*"
126+
3) (integer) 1
127+
128+
1) "pmessage"
129+
2) "*"
130+
3) "socket.io#/#" (a broadcast to all sockets or to a list of rooms)
131+
4) <the packet content>
132+
133+
1) "pmessage"
134+
2) "*"
135+
3) "socket.io#/#room21#" (a broadcast to a single room)
136+
4) <the packet content>
137+
```
138+
139+
Note: **no data** is stored in Redis itself
140+
141+
There are 3 Redis subscriptions per namespace:
142+
143+
- main channel: `<prefix>#<namespace>#*` (glob)
144+
- request channel: `<prefix>-request#<namespace>#`
145+
- response channel: `<prefix>-response#<namespace>#`
146+
147+
The request and response channels are used in the additional methods exposed by the Redis adapter, like [RedisAdapter#allRooms()](#redisadapterallrooms).
148+
149+
94150
## API
95151

96152
### adapter(uri[, opts])

0 commit comments

Comments
 (0)