Server API - Socket - IO
Server API - Socket - IO
On this page
Server API
Server
installation
initialization
details of the server instance
Constructor
new Server(httpServer[, options])
options <Object>
httpServer.listen(3000);
port <number>
options <Object>
new Server(options)
options <Object>
Events
Event: 'connect'
Event: 'connection'
Event: 'new_namespace'
namespace Namespace
Attributes
server.engine
server.sockets
<Namespace>
io.sockets.emit("hi", "everyone");
// is equivalent to
io.of("/").emit("hi", "everyone");
Methods
server.adapter([value])
value <Adapter>
Sets the adapter value . Defaults to an instance of the Adapter that ships with socket.io which is
memory based. See socket.io-adapter. If no arguments are supplied this method returns the
current value.
io.adapter(createAdapter(pubClient, subClient));
// redis@3
io.listen(3000);
// redis@4
Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
io.listen(3000);
});
server.attach(httpServer[, options])
options <Object>
io.attach(httpServer);
httpServer.listen(3000);
server.attach(port[, options])
port <number>
options <Object>
Attaches the Server on the given port with the supplied options .
server.attachApp(app[, options])
app <uws.App>
options <Object>
io.attachApp(app);
server.bind(engine)
engine <engine.Server>
Returns <Server>
Advanced use only. Binds the server to a specific engine.io Server (or compatible API) instance.
io.bind(engine);
engine.listen(3000);
server.close([callback])
callback <Function>
Closes the Socket.IO server and disconnect all clients. The callback argument is optional and
will be called when all connections are closed.
INFO
io.close();
io.attach(httpServer);
NOTE
Only closing the underlying HTTP server is not sufficient, as it will only prevent the server
from accepting new connections but clients connected with WebSocket will not be
disconnected right away.
Reference: https://nodejs.org/api/http.html#serverclosecallback
server.disconnectSockets([close])
Added in v4.0.0
Alias for io.of("/").disconnectSockets(close) .
// make all Socket instances in the "room1" room disconnect (and close the
low-level connection)
io.in("room1").disconnectSockets(true);
TIP
This method also works within a cluster of multiple Socket.IO servers, with a compatible
adapter like the Postgres adapter.
In that case, if you only want to affect the socket instances on the given node, you need to
use the local flag:
// make all Socket instances that are currently connected on the given
node disconnect
io.local.disconnectSockets();
See here.
server.emit(eventName[, ...args])
History
args any[]
Returns true
io.emit("hello");
Any number of parameters can be included, and all serializable data structures are supported:
io.emit("hello", 1, "2", { "3": 4 }, Buffer.from([5]));
INFO
You can use to() and except() to send the packet to specific clients:
// the “hello” event will be broadcast to all connected clients that are
either
// in the "room1" room or in the "room2" room, excluding those in the "room3"
room
io.to("room1").to("room2").except("room3").emit("hello");
Starting with version 4.5.0 , it is now possible to use acknowledgements when broadcasting:
CAUTION
server.emitWithAck(eventName[, ...args])
Added in v4.6.0
args any[]
Returns Promise<any[]>
try {
const responses = await io.timeout(10000).emitWithAck("some-event");
console.log(responses); // one response per client
} catch (e) {
// some clients did not acknowledge the event in the given delay
}
server.except(rooms)
Added in v4.0.0
Returns BroadcastOperator
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have not joined the given rooms .
// the "foo" event will be broadcast to all connected clients, except the ones
that are in the "room-101" room
io.except("room-101").emit("foo", "bar");
server.fetchSockets()
Added in v4.0.0
// return all Socket instances in the "room1" room of the main namespace
const sockets = await io.in("room1").fetchSockets();
Sample usage:
socket.join(userId);
TIP
This method also works within a cluster of multiple Socket.IO servers, with a compatible
adapter like the Postgres adapter.
In that case, if you only want to return the socket instances on the given node, you need to
use the local flag:
// return all Socket instances that are currently connected on the given
node
const sockets = await io.local.fetchSockets();
See here.
server.in(room)
Added in v1.0.0
server.listen(httpServer[, options])
server.listen(port[, options])
server.of(nsp)
Returns <Namespace>
Initializes and retrieves the given Namespace by its pathname identifier nsp . If the namespace
was already initialized it returns it immediately.
A regex or a function can also be provided, in order to create namespace in a dynamic way:
const dynamicNsp = io.of(/^\/dynamic-\d+$/).on("connection", (socket) => {
const newNamespace = socket.nsp; // newNamespace.name === "/dynamic-101"
// client-side
const socket = io("/dynamic-101");
With a function:
server.on(eventName, listener)
listener <Function>
Returns <Server>
Adds the listener function to the end of the listeners array for the event named eventName .
Available events:
connection
new_namespace
server.onconnection(socket)
socket <engine.Socket>
Returns <Server>
Advanced use only. Creates a new socket.io client from the incoming engine.io (or compatible
API) Socket .
engine.listen(3000);
server.path([value])
value <string>
Sets the path value under which engine.io and the static files will be served. Defaults to
/socket.io/ . If no arguments are supplied this method returns the current value.
io.path("/myownpath/");
WARNING
The path value must match the one on the client side:
server.serveClient([value])
value <boolean>
If value is true the attached server will serve the client files. Defaults to true . This method has
no effect after listen is called. If no arguments are supplied this method returns the current
value.
io.serveClient(false);
io.listen(3000);
Added in v4.1.0
eventName <string>
args <any[]>
ack <Function>
Returns true
Syntax:
io.serverSideEmit("hello", "world");
// server A
io.serverSideEmit("ping", (err, responses) => {
console.log(responses[0]); // prints "pong"
});
// server B
io.on("ping", (cb) => {
cb("pong");
});
Notes:
the connection , connect and new_namespace strings are reserved and cannot be used in
your application.
you can send any number of arguments, but binary structures are currently not supported
(the array of arguments will be JSON.stringify -ed)
Example:
the acknowledgement callback might be called with an error, if the other Socket.IO servers
do not respond after a given delay
server.serverSideEmitWithAck(eventName[, ...args])
Added in v4.6.0
eventName <string>
args <any[]>
ack <Function>
Returns Promise<any[]>
try {
const responses = await io.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
}
server.socketsJoin(rooms)
Added in v4.0.0
// make all Socket instances in the "room1" room join the "room2" and "room3"
rooms
io.in("room1").socketsJoin(["room2", "room3"]);
TIP
This method also works within a cluster of multiple Socket.IO servers, with a compatible
adapter like the Postgres adapter.
In that case, if you only want to affect the socket instances on the given node, you need to
use the local flag:
// make all Socket instances that are currently connected on the given
node join the "room1" room
io.local.socketsJoin("room1");
See here.
server.socketsLeave(rooms)
Added in v4.0.0
// make all Socket instances in the "room1" room leave the "room2" and "room3"
rooms
io.in("room1").socketsLeave(["room2", "room3"]);
TIP
This method also works within a cluster of multiple Socket.IO servers, with a compatible
adapter like the Postgres adapter.
In that case, if you only want to affect the socket instances on the given node, you need to
use the local flag:
// make all Socket instances that are currently connected on the given
node leave the "room1" room
io.local.socketsLeave("room1");
See here.
server.timeout(value)
Added in v4.5.0
value <number>
Returns BroadcastOperator
Sets a modifier for a subsequent event emission that the callback will be called with an error
when the given number of milliseconds have elapsed without an acknowledgement from all
targeted clients:
server.to(room)
History
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have joined the given room .
// the “foo” event will be broadcast to all connected clients in the “room-
101” room
io.to("room-101").emit("foo", "bar");
server.use(fn)
Added in v1.0.0
fn <Function>
Registers a middleware for the main namespace, which is a function that gets executed for every
incoming Socket , and receives as parameters the socket and a function to optionally defer
execution to the next registered middleware.
Errors passed to middleware callbacks are sent as special connect_error packets to clients.
Server
io.of("/chat").use((socket, next) => {
const err = new Error("not authorized");
err.data = { content: "Please retry later" }; // additional details
next(err);
});
Client
INFO
If you are looking for Express middlewares, please check this section.
Namespace
Represents a pool of sockets connected under a given scope identified by a pathname (eg:
/chat ).
More information can be found here.
Attributes
namespace.adapter
<Adapter>
Note: the adapter of the main namespace can be accessed with io.of("/").adapter .
namespace.name
<string>
namespace.sockets
Map<SocketId, Socket>
Events
Event: 'connect'
Event: 'connection'
socket <Socket>
Fired upon a connection from client.
// main namespace
io.on("connection", (socket) => {
// ...
});
// custom namespace
io.of("/admin").on("connection", (socket) => {
// ...
});
Methods
namespace.allSockets()
Returns Promise<Set<SocketId>>
CAUTION
This method will be removed in the next major release, please use serverSideEmit() or
fetchSockets() instead.
Gets a list of socket IDs connected to this namespace (across all nodes if applicable).
namespace.disconnectSockets([close])
Added in v4.0.0
// make all Socket instances in the "room1" room disconnect (and discard the
low-level connection)
io.in("room1").disconnectSockets(true);
// make all Socket instances in the "room1" room of the "admin" namespace
disconnect
io.of("/admin").in("room1").disconnectSockets();
namespace.emit(eventName[, ...args])
History
args any[]
Returns true
io.of("/chat").emit("hello");
Any number of parameters can be included, and all serializable data structures are supported:
INFO
You can use to() and except() to send the packet to specific clients:
// the “hello” event will be broadcast to all connected clients that are
either
// in the "room1" room or in the "room2" room, excluding those in the "room3"
room
io.of("/chat").to("room1").to("room2").except("room3").emit("hello");
Starting with version 4.5.0 , it is now possible to use acknowledgements when broadcasting:
CAUTION
namespace.emitWithAck(eventName[, ...args])
Added in v4.6.0
args any[]
Returns Promise<any[]>
namespace.except(rooms)
Added in v4.0.0
Returns BroadcastOperator
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have not joined the given rooms .
// the "foo" event will be broadcast to all connected clients, except the ones
that are in the "room-101" room
myNamespace.except("room-101").emit("foo", "bar");
namespace.fetchSockets()
Added in v4.0.0
// return all Socket instances in the "room1" room of the main namespace
const sockets = await io.in("room1").fetchSockets();
// return all Socket instances in the "room1" room of the "admin" namespace
const sockets = await io.of("/admin").in("room1").fetchSockets();
The sockets variable in the example above is an array of objects exposing a subset of the usual
Socket class:
The data attribute is an arbitrary object that can be used to share information between
Socket.IO servers:
// server A
io.on("connection", (socket) => {
socket.data.username = "alice";
});
// server B
const sockets = await io.fetchSockets();
console.log(sockets[0].data.username); // "alice"
Important note: this method (and socketsJoin , socketsLeave and disconnectSockets too)
is compatible with the Redis adapter (starting with [email protected] ), which means that
they will work across Socket.IO servers.
namespace.in(room)
Added in v1.0.0
Added in v4.1.0
eventName <string>
args <any[]>
ack <Function>
Returns true
Syntax:
io.of("/chat")serverSideEmit("hello", "world");
// server A
io.of("/chat").serverSideEmit("ping", (err, responses) => {
console.log(responses[0]); // prints "pong"
});
// server B
io.of("/chat").on("ping", (cb) => {
cb("pong");
});
Notes:
the connection , connect and new_namespace strings are reserved and cannot be used in
your application.
you can send any number of arguments, but binary structures are currently not supported
(the array of arguments will be JSON.stringify -ed)
Example:
the acknowledgement callback might be called with an error, if the other Socket.IO servers
do not respond after a given delay
namespace.serverSideEmitWithAck(eventName[, ...args])
Added in v4.6.0
eventName <string>
args <any[]>
ack <Function>
Returns Promise<any[]>
try {
const responses = await io.of("/chat").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
}
namespace.socketsJoin(rooms)
Added in v4.0.0
Returns void
// make all Socket instances in the "room1" room join the "room2" and "room3"
rooms
io.in("room1").socketsJoin(["room2", "room3"]);
// make all Socket instances in the "room1" room of the "admin" namespace join
the "room2" room
io.of("/admin").in("room1").socketsJoin("room2");
namespace.socketsLeave(rooms)
Added in v4.0.0
Returns void
// make all Socket instances in the "room1" room leave the "room2" and "room3"
rooms
io.in("room1").socketsLeave(["room2", "room3"]);
// make all Socket instances in the "room1" room of the "admin" namespace
leave the "room2" room
io.of("/admin").in("room1").socketsLeave("room2");
// this also works with a single socket ID
io.in(theSocketId).socketsLeave("room1");
namespace.timeout(value)
Added in v4.5.0
value <number>
Returns BroadcastOperator
Sets a modifier for a subsequent event emission that the callback will be called with an error
when the given number of milliseconds have elapsed without an acknowledgement from the
client:
namespace.to(room)
History
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have joined the given room .
// the “foo” event will be broadcast to all connected clients in the “room-
101” room
myNamespace.to("room-101").emit("foo", "bar");
// with an array of rooms (a client will be notified at most once)
myNamespace.to(["room-101", "room-102"]).emit("foo", "bar");
namespace.use(fn)
Added in v1.0.0
fn <Function>
Registers a middleware for the given namespace, which is a function that gets executed for every
incoming Socket , and receives as parameters the socket and a function to optionally defer
execution to the next registered middleware.
Errors passed to middleware callbacks are sent as special connect_error packets to clients.
Server
Client
INFO
If you are looking for Express middlewares, please check this section.
Flags
Flag: 'local'
Sets a modifier for a subsequent event emission that the event data will only be broadcast to the
current node (when scaling to multiple nodes).
Flag: 'volatile'
Sets a modifier for a subsequent event emission that the event data may be lost if the clients are
not ready to receive messages (because of network slowness or other issues, or because they’re
connected through long polling and is in the middle of a request-response cycle).
io.volatile.emit("an event", { some: "data" }); // the clients may or may not
receive it
Socket
A Socket is the fundamental class for interacting with browser clients. A Socket belongs to a
certain Namespace (by default / ) and uses an underlying Client to communicate.
It should be noted the Socket doesn't relate directly to the actual underlying TCP/IP socket
and it is only the name of the class.
Within each Namespace , you can also define arbitrary channels (called room ) that the Socket
can join and leave. That provides a convenient way to broadcast to a group of Socket s (see
Socket#to below).
The Socket class inherits from EventEmitter. The Socket class overrides the emit method, and
does not modify any other EventEmitter method. All methods documented here which also
appear as EventEmitter methods (apart from emit ) are implemented by EventEmitter , and
documentation for EventEmitter applies.
Events
Event: 'disconnect'
Possible reasons:
Reason Description
server namespace
The socket was forcefully disconnected with socket.disconnect().
disconnect
client namespace The client has manually disconnected the socket using
disconnect socket.disconnect().
server shutting
The server is, well, shutting down.
down
ping timeout The client did not send a PONG packet in the pingTimeout delay.
Reason Description
The connection was closed (example: the user has lost connection,
transport close
or the network was changed from WiFi to 4G).
parse error The server has received an invalid packet from the client.
forced close The server has received an invalid packet from the client.
forced server The client did not join a namespace in time (see the
close connectTimeout option) and was forcefully closed.
Event: 'disconnecting'
Fired when the client is going to be disconnected (but hasn't left its rooms yet).
Note: those events, along with connect , connect_error , newListener and removeListener ,
are special events that shouldn't be used in your application:
Attributes
socket.client
<Client>
<engine.Socket>
A reference to the underlying Client transport connection (engine.io Socket object). This
allows access to the IO transport layer, which still (mostly) abstracts the actual TCP/IP socket.
socket.conn.once("upgrade", () => {
// called when the transport is upgraded (i.e. from HTTP long-polling to
WebSocket)
console.log("upgraded transport", socket.conn.transport.name); // prints
"websocket"
});
socket.conn.on("drain", () => {
// called when the write buffer is drained
});
socket.data
Added in v4.0.0
An arbitrary object that can be used in conjunction with the fetchSockets() utility method:
TIP
This also works within a Socket.IO cluster, with a compatible adapter like the Postgres
adapter.
socket.handshake
<Object>
{
headers: /* the headers sent as part of the handshake */,
time: /* the date of creation (as string) */,
address: /* the ip of the client */,
xdomain: /* whether the connection is cross-domain */,
secure: /* whether the connection is secure */,
issued: /* the date of creation (as unix timestamp) */,
url: /* the request URL string */,
query: /* the query parameters of the first request */,
auth: /* the authentication payload */
}
Usage:
socket.id
<string>
A unique identifier for the session, that comes from the underlying Client .
CAUTION
The id attribute is an ephemeral ID that is not meant to be used in your application (or
only for debugging purposes) because:
this ID is regenerated after each reconnection (for example when the WebSocket
connection is severed, or when the user refreshes the page)
two different browser tabs will have two different IDs
there is no message queue stored for a given ID on the server (i.e. if the client is
disconnected, the messages sent from the server to this ID are lost)
Please use a regular session ID instead (either sent in a cookie, or stored in the localStorage
and sent in the auth payload).
See also:
socket.request
<http.IncomingMessage>
A getter proxy that returns the reference to the request that originated the underlying
engine.io Client . Useful for accessing request headers such as Cookie or User-Agent .
socket.rooms
Set<string>
socket.join("room1");
});
Methods
socket.compress(value)
Sets a modifier for a subsequent event emission that the event data will only be compressed if
the value is true . Defaults to true when you don't call the method.
socket.disconnect([close])
Returns Socket
Disconnects this socket. If value of close is true , closes the underlying connection. Otherwise, it
just disconnects the namespace.
(overrides EventEmitter.emit )
eventName <string> | <symbol>
args <any[]>
ack <Function>
Returns true
Emits an event to the socket identified by the string name. Any other parameters can be
included. All serializable data structures are supported, including Buffer .
io.on("connection", () => {
socket.emit("hello", "world");
socket.emit("with-binary", 1, "2", { 3: "4", 5: Buffer.from([6]) });
});
The ack argument is optional and will be called with the client's answer.
Server
Client
socket.emitWithAck(eventName[, ...args])
Added in v4.6.0
args any[]
Returns Promise<any>
Promised-based version of emitting and expecting an acknowledgement from the given client:
io.on("connection", async (socket) => {
// without timeout
const response = await socket.emitWithAck("hello", "world");
socket.eventNames()
Inherited from EventEmitter (along with other methods not mentioned here). See the Node.js
documentation for the events module.
socket.except(rooms)
Added in v4.0.0
rooms <string> | <string[]>
Returns BroadcastOperator
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have not joined the given rooms (the socket itself being excluded).
// same as above
socket.except("room1").emit(/* ... */);
// to all clients in "room4" except the ones in "room5" and the sender
socket.to("room4").except("room5").emit(/* ... */);
socket.in(room)
Added in v1.0.0
Synonym of socket.to(room).
socket.join(room)
The mechanics of joining rooms are handled by the Adapter that has been configured (see
Server#adapter above), defaulting to socket.io-adapter.
For your convenience, each socket automatically joins a room identified by its id (see
Socket#id ). This makes it easy to broadcast messages to other sockets:
socket.leave(room)
room <string>
INFO
socket.listenersAny()
Returns <Function[]>
socket.listenersAnyOutgoing()
Added in v4.5.0
Returns <Function[]>
Returns the list of registered catch-all listeners for outgoing packets.
socket.offAny([listener])
listener <Function>
Removes the previously registered listener. If no listener is provided, all catch-all listeners are
removed.
socket.onAny(myListener);
// then, later
socket.offAny(myListener);
socket.offAny();
socket.offAnyOutgoing([listener])
Added in v4.5.0
listener <Function>
Removes the previously registered listener. If no listener is provided, all catch-all listeners are
removed.
socket.onAnyOutgoing(myListener);
socket.on(eventName, callback)
Inherited from the EventEmitter class.
callback <Function>
Returns <Socket>
socket.onAny(callback)
callback <Function>
socket.onAnyOutgoing(callback)
Added in v4.5.0
callback <Function>
Inherited from EventEmitter (along with other methods not mentioned here). See the Node.js
documentation for the events module.
socket.prependAny(callback)
callback <Function>
Register a new catch-all listener. The listener is added to the beginning of the listeners array.
socket.prependAnyOutgoing(callback)
Added in v4.5.0
callback <Function>
Register a new catch-all listener for outgoing packets. The listener is added to the beginning of
the listeners array.
socket.removeAllListeners([eventName])
Inherited from EventEmitter (along with other methods not mentioned here). See the Node.js
documentation for the events module.
socket.removeListener(eventName, listener)
Inherited from EventEmitter (along with other methods not mentioned here). See the Node.js
documentation for the events module.
socket.send([...args][, ack])
args <any[]>
ack <Function>
Returns Socket
socket.timeout(value)
Added in v4.4.0
value <number>
Returns <Socket>
Sets a modifier for a subsequent event emission that the callback will be called with an error
when the given number of milliseconds have elapsed without an acknowledgement from the
client:
socket.to(room)
History
Sets a modifier for a subsequent event emission that the event will only be broadcast to clients
that have joined the given room (the socket itself being excluded).
// to one room
socket.to("others").emit("an event", { some: "data" });
// to multiple rooms
socket.to("room1").to("room2").emit("hello");
// or with an array
socket.to(["room1", "room2"]).emit("hello");
socket.use(fn)
History
fn <Function>
Registers a middleware, which is a function that gets executed for every incoming Packet and
receives as parameter the packet and a function to optionally defer execution to the next
registered middleware.
Errors passed to the middleware callback are then emitted as error events on the server-side:
Flags
Flag: 'broadcast'
Sets a modifier for a subsequent event emission that the event data will only be broadcast to
every sockets but the sender.
Flag: 'volatile'
Sets a modifier for a subsequent event emission that the event data may be lost if the client is
not ready to receive messages (because of network slowness or other issues, or because they’re
connected through long polling and is in the middle of a request-response cycle).
Client
The Client class represents an incoming transport (engine.io) connection. A Client can be
associated with many multiplexed Socket s that belong to different Namespace s.
Attributes
client.conn
<engine.Socket>
client.request
<http.IncomingMessage>
A getter proxy that returns the reference to the request that originated the engine.io
connection. Useful for accessing request headers such as Cookie or User-Agent .
Engine
The Engine.IO server, which manages the WebSocket / HTTP long-polling connections. More
information here.
Events
Event: 'connection_error'
Added in v4.1.0
error <Error>
This event will be emitted when a connection is abnormally closed. Here is the list of possible
error codes:
Code Message
0 "Transport unknown"
1 "Session ID unknown"
3 "Bad request"
4 "Forbidden"
Event: 'headers'
Added in v4.1.0
This event will be emitted just before writing the response headers of each HTTP request of the
session (including the WebSocket upgrade), allowing you to customize them.
Event: 'initial_headers'
Added in v4.1.0
If you need to perform some asynchronous operations, you will need to use the allowRequest
option:
See also:
Attributes
engine.clientsCount
Added in v1.0.0
<number>
The number of currently connected clients.
Methods
engine.generateId
<Function>
io.engine.generateId = () => {
return uuid.v4(); // must be unique across all Socket.IO servers
}
Added in v1.0.0
socket <stream.Duplex> the network socket between the server and client
head <Buffer> the first packet of the upgraded stream (may be empty)
httpServer.listen(3000);
engine.use(middleware)
Added in v4.6.0
<Function>
next();
});
The middlewares will be called for each incoming HTTP requests, including upgrade requests.
io.engine.use(session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}));
Example with helmet :
io.engine.use(helmet());