The Socket instance (server-side)
- emitting and events
- broadcasting events
The Socket instance has a few attributes that may be of use in your application:
Each new connection is assigned a random 20-characters identifier.
This identifier is synced with the value on the client-side.
Upon creation, the Socket joins the room identified by its own id, which means you can use it for private messaging:
io.on("connection", socket => {
socket.on("private message", (anotherSocketId, msg) => {
socket.to(anotherSocketId).emit("private message", socket.id, msg);
});
});
Note: you can’t overwrite this identifier, as it is used in several parts of the Socket.IO codebase.
Socket#handshake
This object contains some details about the handshake that happens at the beginning of the Socket.IO session.
{
headers: /* the headers of the initial request */
query: /* the query params of the initial request */
auth: /* the authentication payload */
time: /* the date of creation (as string) */
issued: /* the date of creation (unix timestamp) */
url: /* the request URL string */
address: /* the ip of the client */
xdomain: /* whether the connection is cross-domain */
secure: /* whether the connection is secure */
}
This is a reference to the the Socket is currently in.
Socket#data
An arbitrary object that can be used in conjunction with the fetchSockets()
utility method:
// server A
io.on("connection", (socket) => {
socket.data.username = "alice";
});
// server B
const sockets = await io.fetchSockets();
console.log(sockets[0].data.username); // "alice"
More information .
As long as you do not overwrite any existing attribute, you can attach any attribute to the Socket instance and use it later:
// in a middleware
io.use(async (socket, next) => {
try {
const user = await fetchUser(socket);
socket.user = user;
next();
} catch (e) {
next(new Error("unknown user"));
}
});
io.on("connection", (socket) => {
console.log(socket.user);
// in a listener
socket.on("set username", (username) => {
socket.username = username;
});
});
Socket middlewares
Those middlewares looks a lot like the usual , except that they are called for each incoming packet:
socket.use(([event, ...args], next) => {
// do something with the packet (logging, authorization, rate limiting...)
// do not forget to call next() at the end
next();
});
The next
method can also be called with an error object. In that case, the event will not reach the registered event handlers and an event will be emitted instead:
On the server-side, the Socket instance emits two special events:
This event is fired by the Socket instance upon disconnection.
io.on("connection", (socket) => {
socket.on("disconnect", (reason) => {
// ...
});
});
Here is the list of possible reasons:
disconnecting
This event is similar to disconnect
but is fired a bit earlier, when the set is not empty yet
io.on("connection", (socket) => {
socket.on("disconnecting", (reason) => {
for (const room of socket.rooms) {
if (room !== socket.id) {
socket.to(room).emit("user has left", socket.id);
}
}
});
});
Note: those events, along with connect
, connect_error
, newListener
and removeListener
, are special events that shouldn’t be used in your application:
Complete API
The complete API exposed by the Socket instance can be found .