Upgrade socket.io from v2 to v3
socket.io and its related libraries such as socket.io-redis-adapter and socket.io-redis-emitter had a few breaking changes in either functions or behaviors since v3 which might cause issues during the v2-to-v3 migration. This post lists what was encountered and how to solve it for specific use cases based on hands-on experience.
Upgrade guide
Basically read the Migrating from 2.x to 3.0 official guide, then:
- For npm packages
- "socket.io": "2.3.0",
- "socket.io-emitter": "3.1.1",
- "socket.io-redis": "5.4.0" ,
+ "socket.io": "3.1.2",
+ "socket.io-emitter": "3.2.0",
+ "socket.io-redis": "6.0.1",
- For server config
const sio = require('socket.io');
//...
this.io = sio(this.http_server, {
// enable compatibility for v2 clients (must; during migration)
allowEIO3: true,
// the same as the default value in v2 (optional; use case specific)
maxHttpBufferSize: 10e7,
// the same as the default value in v2 (optional; use case specific)
perMessageDeflate: true,
cors: {
// must; if to enable cors for any clients; cannot use '*' due to the credentials option below
origin: true,
// must; because v2 socket.io clients will set withCredentials: true
credentials: true,
// optional; use case specific
allowHeaders: 'Accept,Authorization,Content-Type,Origin,X-Requested-With',
},
});
and for cookie
option change, the official guide can be referenced here.
-
For breaking API change
Following the official guide should be fine, and items such as Namespace.connected is renamed to Namespace.sockets and is now a Map and Socket.join() and Socket.leave() are now synchronous need special attention as breaking changes. -
For client change
Replace the event names with new ones such as:
socket.on("error", err => {
console.log(err);
});
// change to
socket.on("connect_error", err => {
console.log(err.message);
});
and update to add listeners to Manager
instead of socket
object:
socket.on("reconnect_attempt", () => {});
// change to
socket.io.on("reconnect_attempt", () => {});
-
For redis-adapter behavior change
Note:
There was a big behavior change insocket-io-redis
adapter since v6.x regarding how redispubClient
andsubClient
are created. In previous versions, the redis clients are created by the adapter and shared by all namespaces during initialization. However, in the newer versions a new pair of redis clients (pubClient
andsubClient
) would be created for each single namespace. This change would cause a huge issue for use cases where lots ofnamespaces
are used in socket-io server.For more details see this issue reported by me during the upgrading.
-
For other tips
The newer versions were rewritten using TypeScript as well as with newer JavaScript syntaxes from ES6+, there might be issues related to webpack and its plugins not being able to handle the build any more and there might be performance issues related to per message deflation, and so on.
References