Skip to content

Commit a2e5d1f

Browse files
chore(release): 4.6.0
Diff: 4.5.4...4.6.0
1 parent d8143cc commit a2e5d1f

12 files changed

+522
-235
lines changed

CHANGELOG.md

+187-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# History
22

3+
## 2023
4+
5+
- [4.6.0](#460-2023-02-07) (Feb 2023)
6+
37
## 2022
48

59
- [4.5.4](#454-2022-11-22) (Nov 2022)
@@ -52,6 +56,187 @@
5256

5357
# Release notes
5458

59+
# [4.6.0](https://github.com/socketio/socket.io/compare/4.5.4...4.6.0) (2023-02-07)
60+
61+
62+
### Bug Fixes
63+
64+
* add timeout method to remote socket ([#4558](https://github.com/socketio/socket.io/issues/4558)) ([0c0eb00](https://github.com/socketio/socket.io/commit/0c0eb0016317218c2be3641e706cfaa9bea39a2d))
65+
* **typings:** properly type emits with timeout ([f3ada7d](https://github.com/socketio/socket.io/commit/f3ada7d8ccc02eeced2b9b9ac8e4bc921eb630d2))
66+
67+
68+
### Features
69+
70+
#### Promise-based acknowledgements
71+
72+
This commit adds some syntactic sugar around acknowledgements:
73+
74+
- `emitWithAck()`
75+
76+
```js
77+
try {
78+
const responses = await io.timeout(1000).emitWithAck("some-event");
79+
console.log(responses); // one response per client
80+
} catch (e) {
81+
// some clients did not acknowledge the event in the given delay
82+
}
83+
84+
io.on("connection", async (socket) => {
85+
// without timeout
86+
const response = await socket.emitWithAck("hello", "world");
87+
88+
// with a specific timeout
89+
try {
90+
const response = await socket.timeout(1000).emitWithAck("hello", "world");
91+
} catch (err) {
92+
// the client did not acknowledge the event in the given delay
93+
}
94+
});
95+
```
96+
97+
- `serverSideEmitWithAck()`
98+
99+
```js
100+
try {
101+
const responses = await io.timeout(1000).serverSideEmitWithAck("some-event");
102+
console.log(responses); // one response per server (except itself)
103+
} catch (e) {
104+
// some servers did not acknowledge the event in the given delay
105+
}
106+
```
107+
108+
Added in [184f3cf](https://github.com/socketio/socket.io/commit/184f3cf7af57acc4b0948eee307f25f8536eb6c8).
109+
110+
#### Connection state recovery
111+
112+
This feature allows a client to reconnect after a temporary disconnection and restore its state:
113+
114+
- id
115+
- rooms
116+
- data
117+
- missed packets
118+
119+
Usage:
120+
121+
```js
122+
import { Server } from "socket.io";
123+
124+
const io = new Server({
125+
connectionStateRecovery: {
126+
// default values
127+
maxDisconnectionDuration: 2 * 60 * 1000,
128+
skipMiddlewares: true,
129+
},
130+
});
131+
132+
io.on("connection", (socket) => {
133+
console.log(socket.recovered); // whether the state was recovered or not
134+
});
135+
```
136+
137+
Here's how it works:
138+
139+
- the server sends a session ID during the handshake (which is different from the current `id` attribute, which is public and can be freely shared)
140+
- the server also includes an offset in each packet (added at the end of the data array, for backward compatibility)
141+
- upon temporary disconnection, the server stores the client state for a given delay (implemented at the adapter level)
142+
- upon reconnection, the client sends both the session ID and the last offset it has processed, and the server tries to restore the state
143+
144+
The in-memory adapter already supports this feature, and we will soon update the Postgres and MongoDB adapters. We will also create a new adapter based on [Redis Streams](https://redis.io/docs/data-types/streams/), which will support this feature.
145+
146+
Added in [54d5ee0](https://github.com/socketio/socket.io/commit/54d5ee05a684371191e207b8089f09fc24eb5107).
147+
148+
#### Compatibility (for real) with Express middlewares
149+
150+
This feature implements middlewares at the Engine.IO level, because Socket.IO middlewares are meant for namespace authorization and are not executed during a classic HTTP request/response cycle.
151+
152+
Syntax:
153+
154+
```js
155+
io.engine.use((req, res, next) => {
156+
// do something
157+
158+
next();
159+
});
160+
161+
// with express-session
162+
import session from "express-session";
163+
164+
io.engine.use(session({
165+
secret: "keyboard cat",
166+
resave: false,
167+
saveUninitialized: true,
168+
cookie: { secure: true }
169+
}));
170+
171+
// with helmet
172+
import helmet from "helmet";
173+
174+
io.engine.use(helmet());
175+
```
176+
177+
A workaround was possible by using the allowRequest option and the "headers" event, but this feels way cleaner and works with upgrade requests too.
178+
179+
Added in [24786e7](https://github.com/socketio/engine.io/commit/24786e77c5403b1c4b5a2bc84e2af06f9187f74a).
180+
181+
#### Error details in the disconnecting and disconnect events
182+
183+
The `disconnect` event will now contain additional details about the disconnection reason.
184+
185+
```js
186+
io.on("connection", (socket) => {
187+
socket.on("disconnect", (reason, description) => {
188+
console.log(description);
189+
});
190+
});
191+
```
192+
193+
Added in [8aa9499](https://github.com/socketio/socket.io/commit/8aa94991cee5518567d6254eec04b23f81510257).
194+
195+
#### Automatic removal of empty child namespaces
196+
197+
This commit adds a new option, "cleanupEmptyChildNamespaces". With this option enabled (disabled by default), when a socket disconnects from a dynamic namespace and if there are no other sockets connected to it then the namespace will be cleaned up and its adapter will be closed.
198+
199+
```js
200+
import { createServer } from "node:http";
201+
import { Server } from "socket.io";
202+
203+
const httpServer = createServer();
204+
const io = new Server(httpServer, {
205+
cleanupEmptyChildNamespaces: true
206+
});
207+
```
208+
209+
Added in [5d9220b](https://github.com/socketio/socket.io/commit/5d9220b69adf73e086c27bbb63a4976b348f7c4c).
210+
211+
#### A new "addTrailingSlash" option
212+
213+
The trailing slash which was added by default can now be disabled:
214+
215+
```js
216+
import { createServer } from "node:http";
217+
import { Server } from "socket.io";
218+
219+
const httpServer = createServer();
220+
const io = new Server(httpServer, {
221+
addTrailingSlash: false
222+
});
223+
```
224+
225+
In the example above, the clients can omit the trailing slash and use `/socket.io` instead of `/socket.io/`.
226+
227+
Added in [d0fd474](https://github.com/socketio/engine.io/commit/d0fd4746afa396297f07bb62e539b0c1c4018d7c).
228+
229+
### Performance Improvements
230+
231+
* precompute the WebSocket frames when broadcasting ([da2b542](https://github.com/socketio/socket.io/commit/da2b54279749adc5279c9ac4742b01b36c01cff0))
232+
233+
234+
### Dependencies
235+
236+
- [`engine.io@~6.4.0`](https://github.com/socketio/engine.io/releases/tag/6.4.0) ([diff](https://github.com/socketio/engine.io/compare/6.2.0...6.2.1))
237+
- [`ws@~8.11.0`](https://github.com/websockets/ws/releases/tag/8.11.0) ([diff](https://github.com/websockets/ws/compare/8.2.3...8.11.0))
238+
239+
55240
## [4.5.4](https://github.com/socketio/socket.io/compare/4.5.3...4.5.4) (2022-11-22)
56241

57242
This release contains a bump of:
@@ -61,8 +246,8 @@ This release contains a bump of:
61246

62247
### Dependencies
63248

64-
- [`engine.io@~6.2.1`](https://github.com/socketio/engine.io-client/tree/6.2.1) ([diff](https://github.com/socketio/engine.io/compare/6.2.0...6.2.1))
65-
- [`ws@~8.2.3`](https://github.com/websockets/ws/releases/tag/8.2.3)
249+
- [`engine.io@~6.2.1`](https://github.com/socketio/engine.io/releases/tag/6.2.1) ([diff](https://github.com/socketio/engine.io/compare/6.2.0...6.2.1))
250+
- [`ws@~8.2.3`](https://github.com/websockets/ws/releases/tag/8.2.3) (no change)
66251

67252

68253

client-dist/socket.io.esm.min.js

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client-dist/socket.io.esm.min.js.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)