Realtime application framework (Node.JS server)
MIT License
Bot releases are hidden (Show)
engine.io@~6.5.2
(no change)ws@~8.11.0
(no change)Published by darrachequesne 9 months ago
engine.io@~6.5.2
(no change)ws@~8.11.0
(no change)Published by darrachequesne 10 months ago
engine.io@~6.5.2
(no change)ws@~8.11.0
(no change)Published by darrachequesne about 1 year ago
engine.io@~6.5.2
(diff)ws@~8.11.0
(no change)Published by darrachequesne over 1 year ago
The client bundle contains a few fixes regarding the WebTransport support.
engine.io@~6.5.0
(no change)ws@~8.11.0
(no change)Published by darrachequesne over 1 year ago
The Socket.IO server can now use WebTransport as the underlying transport.
WebTransport is a web API that uses the HTTP/3 protocol as a bidirectional transport. It's intended for two-way communications between a web client and an HTTP/3 server.
References:
Until WebTransport support lands in Node.js, you can use the @fails-components/webtransport
package:
import { readFileSync } from "fs";
import { createServer } from "https";
import { Server } from "socket.io";
import { Http3Server } from "@fails-components/webtransport";
// WARNING: the total length of the validity period MUST NOT exceed two weeks (https://w3c.github.io/webtransport/#custom-certificate-requirements)
const cert = readFileSync("/path/to/my/cert.pem");
const key = readFileSync("/path/to/my/key.pem");
const httpsServer = createServer({
key,
cert
});
httpsServer.listen(3000);
const io = new Server(httpsServer, {
transports: ["polling", "websocket", "webtransport"] // WebTransport is not enabled by default
});
const h3Server = new Http3Server({
port: 3000,
host: "0.0.0.0",
secret: "changeit",
cert,
privKey: key,
});
(async () => {
const stream = await h3Server.sessionStream("/socket.io/");
const sessionReader = stream.getReader();
while (true) {
const { done, value } = await sessionReader.read();
if (done) {
break;
}
io.engine.onWebTransportSession(value);
}
})();
h3Server.startServer();
Added in 123b68c.
The bundles will now have the right Access-Control-Allow-xxx
headers.
Added in 63f181c.
engine.io@~6.5.0
(diff)ws@~8.11.0
(no change)Published by darrachequesne over 1 year ago
engine.io@~6.4.2
(diff)ws@~8.11.0
(no change)Published by darrachequesne over 1 year ago
engine.io@~6.4.1
(diff)ws@~8.11.0
(no change)Published by darrachequesne over 1 year ago
This commit adds some syntactic sugar around acknowledgements:
emitWithAck()
try {
const responses = await io.timeout(1000).emitWithAck("some-event");
console.log(responses); // one response per client
} catch (e) {
// some clients did not acknowledge the event in the given delay
}
io.on("connection", async (socket) => {
// without timeout
const response = await socket.emitWithAck("hello", "world");
// with a specific timeout
try {
const response = await socket.timeout(1000).emitWithAck("hello", "world");
} catch (err) {
// the client did not acknowledge the event in the given delay
}
});
serverSideEmitWithAck()
try {
const responses = await io.timeout(1000).serverSideEmitWithAck("some-event");
console.log(responses); // one response per server (except itself)
} catch (e) {
// some servers did not acknowledge the event in the given delay
}
Added in 184f3cf.
This feature allows a client to reconnect after a temporary disconnection and restore its state:
Usage:
import { Server } from "socket.io";
const io = new Server({
connectionStateRecovery: {
// default values
maxDisconnectionDuration: 2 * 60 * 1000,
skipMiddlewares: true,
},
});
io.on("connection", (socket) => {
console.log(socket.recovered); // whether the state was recovered or not
});
Here's how it works:
id
attribute, which is public and can be freely shared)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, which will support this feature.
Added in 54d5ee0.
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.
Syntax:
io.engine.use((req, res, next) => {
// do something
next();
});
// with express-session
import session from "express-session";
io.engine.use(session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
// with helmet
import helmet from "helmet";
io.engine.use(helmet());
A workaround was possible by using the allowRequest option and the "headers" event, but this feels way cleaner and works with upgrade requests too.
Added in 24786e7.
The disconnect
event will now contain additional details about the disconnection reason.
io.on("connection", (socket) => {
socket.on("disconnect", (reason, description) => {
console.log(description);
});
});
Added in 8aa9499.
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.
import { createServer } from "node:http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
cleanupEmptyChildNamespaces: true
});
Added in 5d9220b.
The trailing slash which was added by default can now be disabled:
import { createServer } from "node:http";
import { Server } from "socket.io";
const httpServer = createServer();
const io = new Server(httpServer, {
addTrailingSlash: false
});
In the example above, the clients can omit the trailing slash and use /socket.io
instead of /socket.io/
.
Added in d0fd474.
engine.io@~6.4.0
(diff)ws@~8.11.0
(diff)Published by darrachequesne almost 2 years ago
This release contains a bump of:
engine.io
in order to fix CVE-2022-41940
socket.io-parser
in order to fix CVE-2022-2421.engine.io@~6.2.1
(diff)ws@~8.2.3
Published by darrachequesne about 2 years ago
~6.2.0
~8.2.3
Published by darrachequesne about 2 years ago
~6.2.0
~8.2.3
Published by darrachequesne over 2 years ago
⚠️ WARNING ⚠️
The default value of the maxHttpBufferSize
option has been decreased from 100 MB to 1 MB, in order to prevent attacks by denial of service.
Security advisory: https://github.com/advisories/GHSA-j4f2-536g-r55m
~3.6.0
(diff)~7.4.2
Published by darrachequesne over 2 years ago
~6.2.0
~8.2.3
Published by darrachequesne over 2 years ago
This is similar to onAny()
, but for outgoing packets.
Syntax:
socket.onAnyOutgoing((event, ...args) => {
console.log(event);
});
Syntax:
io.timeout(1000).emit("some-event", (err, responses) => {
// ...
});
So that clients in HTTP long-polling can decide how many packets they have to send to stay under the maxHttpBufferSize
value.
This is a backward compatible change which should not mandate a new major revision of the protocol (we stay in v4), as
we only add a field in the JSON-encoded handshake data:
0{"sid":"lv_VI97HAXpY6yYWAAAC","upgrades":["websocket"],"pingInterval":25000,"pingTimeout":5000,"maxPayload":1000000}
~6.2.0
(diff)~8.2.3
Published by darrachequesne almost 3 years ago
Published by darrachequesne almost 3 years ago
const { App } = require("uWebSockets.js");
const { Server } = require("socket.io");
const app = new App();
const io = new Server();
io.attachApp(app);
io.on("connection", (socket) => {
// ...
});
app.listen(3000, (token) => {
if (!token) {
console.warn("port already in use");
}
});
socket.timeout(5000).emit("my-event", (err) => {
if (err) {
// the client did not acknowledge the event in the given delay
}
});
interface SocketData {
name: string;
age: number;
}
const io = new Server<ClientToServerEvents, ServerToClientEvents, InterServerEvents, SocketData>();
io.on("connection", (socket) => {
socket.data.name = "john";
socket.data.age = 42;
});
~6.1.0
(diff)~8.2.3
Published by darrachequesne almost 3 years ago
~6.0.0
~8.2.3
Published by darrachequesne about 3 years ago
~6.0.0
~8.2.3
Published by darrachequesne about 3 years ago
For this release, most of the work was done on the client side, see here.
~6.0.0
(diff)~8.2.3
(diff)