Server API
Server
Exposed by require('socket.io')
.
new Server(httpServer[, options])
httpServer
(http.Server) the server to bind to.options
(Object)
Works with and without new
:
const io = require('socket.io')();
// or
const Server = require('socket.io');
const io = new Server();
Available options:
Option | Default value | Description |
---|---|---|
path | /socket.io | name of the path to capture |
serveClient | true | whether to serve the client files |
adapter | - | the adapter to use. Defaults to an instance of the Adapter that ships with socket.io which is memory based. See socket.io-adapter |
origins | * | the allowed origins |
parser | - | the parser to use. Defaults to an instance of the Parser that ships with socket.io. See socket.io-parser. |
Available options for the underlying Engine.IO server:
Option | Default value | Description |
---|---|---|
pingTimeout | 5000 | how many ms without a pong packet to consider the connection closed |
pingInterval | 25000 | how many ms before sending a new ping packet |
upgradeTimeout | 10000 | how many ms before an uncompleted transport upgrade is cancelled |
maxHttpBufferSize | 10e7 | how many bytes or characters a message can be, before closing the session (to avoid DoS). |
allowRequest | A function that receives a given handshake or upgrade request as its first parameter, and can decide whether to continue or not. The second argument is a function that needs to be called with the decided information: fn(err, success) , where success is a boolean value where false means that the request is rejected, and err is an error code. | |
transports | ['polling', 'websocket'] | transports to allow connections to |
allowUpgrades | true | whether to allow transport upgrades |
perMessageDeflate | false | parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to true to disable. |
httpCompression | true | parameters of the http compression for the polling transports (see zlib api docs). Set to false to disable. |
cookie | io | name of the HTTP cookie that contains the client sid to send as part of handshake response headers. Set to false to not send one. |
cookiePath | / | path of the above cookie option. If false, no path will be sent, which means browsers will only send the cookie on the engine.io attached path (/engine.io ). Set false to not save io cookie on all requests. |
cookieHttpOnly | true | if true HttpOnly io cookie cannot be accessed by client-side APIs, such as JavaScript. This option has no effect if cookie or cookiePath is set to false . |
wsEngine | ws | what WebSocket server implementation to use. Specified module must conform to the ws interface (see ws module api docs). Default value is ws . An alternative c++ addon is also available by installing the eiows module. |
Among those options:
The
pingTimeout
andpingInterval
parameters will impact the delay before a client knows the server is not available anymore. For example, if the underlying TCP connection is not closed properly due to a network issue, a client may have to wait up topingTimeout + pingInterval
ms before getting adisconnect
event.The order of the
transports
array is important. By default, a long-polling connection is established first, and then upgraded to WebSocket if possible. Using['websocket']
means there will be no fallback if a WebSocket connection cannot be opened.
const server = require('http').createServer();
const io = require('socket.io')(server, {
path: '/test',
serveClient: false,
// below are engine.IO options
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
server.listen(3000);
new Server(port[, options])
port
(Number) a port to listen to (a newhttp.Server
will be created)options
(Object)
See above for the list of available options
.
const io = require('socket.io')(3000, {
path: '/test',
serveClient: false,
// below are engine.IO options
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
new Server(options)
options
(Object)
See above for the list of available options
.
const io = require('socket.io')({
path: '/test',
serveClient: false,
});
// either
const server = require('http').createServer();
io.attach(server, {
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
server.listen(3000);
// or
io.attach(3000, {
pingInterval: 10000,
pingTimeout: 5000,
cookie: false
});
server.sockets
- (Namespace)
An alias for the default (/
) namespace.
io.sockets.emit('hi', 'everyone');
// is equivalent to
io.of('/').emit('hi', 'everyone');
server.serveClient([value])
value
(Boolean)- Returns
Server|Boolean
If value
is true
the attached server (see Server#attach
) will serve the client files. Defaults to true
. This method has no effect after attach
is called. If no arguments are supplied this method returns the current value.
// pass a server and the `serveClient` option
const io = require('socket.io')(http, { serveClient: false });
// or pass no server and then you can call the method
const io = require('socket.io')();
io.serveClient(false);
io.attach(http);
server.path([value])
value
(String)- Returns
Server|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.
const io = require('socket.io')();
io.path('/myownpath');
// client-side
const socket = io({
path: '/myownpath'
});
server.adapter([value])
value
(Adapter)- Returns
Server|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.
const io = require('socket.io')(3000);
const redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
server.origins([value])
value
(String|String[])- Returns
Server|String
Sets the allowed origins value
. Defaults to any origins being allowed. If no arguments are supplied this method returns the current value.
io.origins(['https://foo.example.com:443']);
server.origins(fn)
fn
(Function)- Returns
Server
Provides a function taking two arguments origin:String
and callback(error, success)
, where success
is a boolean value indicating whether origin is allowed or not. If success
is set to false
, error
must be provided as a string value that will be appended to the server response, e.g. "Origin not allowed".
Potential drawbacks:
- in some situations, when it is not possible to determine
origin
it may have value of*
- As this function will be executed for every request, it is advised to make this function work as fast as possible
- If
socket.io
is used together withExpress
, the CORS headers will be affected only forsocket.io
requests. For Express you can use cors.
io.origins((origin, callback) => {
if (origin !== 'https://foo.example.com') {
return callback('origin not allowed', false);
}
callback(null, true);
});
server.attach(httpServer[, options])
httpServer
(http.Server) the server to attach tooptions
(Object)
Attaches the Server
to an engine.io instance on httpServer
with the supplied options
(optionally).
server.attach(port[, options])
port
(Number) the port to listen onoptions
(Object)
Attaches the Server
to an engine.io instance on a new http.Server with the supplied options
(optionally).
server.listen(httpServer[, options])
Synonym of server.attach(httpServer[, options]).
server.listen(port[, options])
Synonym of server.attach(port[, options]).
server.bind(engine)
engine
(engine.Server)- Returns
Server
Advanced use only. Binds the server to a specific engine.io Server
(or compatible API) instance.
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
.
server.of(nsp)
nsp
(String|RegExp|Function)- Returns
Namespace
Initializes and retrieves the given Namespace
by its pathname identifier nsp
. If the namespace was already initialized it returns it immediately.
const adminNamespace = io.of('/admin');
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'
// broadcast to all clients in the given sub-namespace
newNamespace.emit('hello');
});
// client-side
const socket = io('/dynamic-101');
// broadcast to all clients in each sub-namespace
dynamicNsp.emit('hello');
// use a middleware for each sub-namespace
dynamicNsp.use((socket, next) => { /* ... */ });
With a function:
io.of((name, query, next) => {
// the checkToken method must return a boolean, indicating whether the client is able to connect or not.
next(null, checkToken(query.token));
}).on('connection', (socket) => { /* ... */ });
server.close([callback])
callback
(Function)
Closes the socket.io server. The callback
argument is optional and will be called when all connections are closed.
const Server = require('socket.io');
const PORT = 3030;
const server = require('http').Server();
const io = Server(PORT);
io.close(); // Close current server
server.listen(PORT); // PORT is free to use
io = Server(server);
server.engine.generateId
Overwrites the default method to generate your custom socket id.
The function is called with a node request object (http.IncomingMessage
) as first parameter.
io.engine.generateId = (req) => {
return "custom:id:" + custom_id++; // custom id must be unique
}
Namespace
Represents a pool of sockets connected under a given scope identified by a pathname (eg: /chat
).
A client always connects to /
(the main namespace), then potentially connect to other namespaces (while using the same underlying connection).
For the how and why, please take a look at: Rooms and Namespaces.
namespace.name
- (String)
The namespace identifier property.
namespace.connected
_(Object<Socket>)_
The hash of Socket
objects that are connected to this namespace, indexed by id
.
namespace.adapter
- (Adapter)
The Adapter
used for the namespace. Useful when using the Adapter
based on Redis, as it exposes methods to manage sockets and rooms across your cluster.
Note: the adapter of the main namespace can be accessed with io.of('/').adapter
.
namespace.to(room)
room
(String)- Returns
Namespace
for chaining
Sets a modifier for a subsequent event emission that the event will only be broadcasted to clients that have joined the given room
.
To emit to multiple rooms, you can call to
several times.
const io = require('socket.io')();
const adminNamespace = io.of('/admin');
adminNamespace.to('level1').emit('an event', { some: 'data' });
namespace.in(room)
Synonym of namespace.to(room).
namespace.emit(eventName[, ...args])
eventName
(String)args
Emits an event to all connected clients. The following two are equivalent:
const io = require('socket.io')();
io.emit('an event sent to all connected clients'); // main namespace
const chat = io.of('/chat');
chat.emit('an event sent to all connected clients in chat namespace');
Note: acknowledgements are not supported when emitting from namespace.
namespace.clients(callback)
callback
(Function)
Gets a list of client IDs connected to this namespace (across all nodes if applicable).
const io = require('socket.io')();
io.of('/chat').clients((error, clients) => {
if (error) throw error;
console.log(clients); // => [PZDoMHjiu8PYfRiKAAAF, Anw2LatarvGVVXEIAAAD]
});
An example to get all clients in namespace's room:
io.of('/chat').in('general').clients((error, clients) => {
if (error) throw error;
console.log(clients); // => [Anw2LatarvGVVXEIAAAD]
});
As with broadcasting, the default is all clients from the default namespace ('/'):
io.clients((error, clients) => {
if (error) throw error;
console.log(clients); // => [6em3d4TJP8Et9EMNAAAA, G5p55dHhGgUnLUctAAAB]
});
namespace.use(fn)
fn
(Function)
Registers a middleware, 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 error
packets to clients.
io.use((socket, next) => {
if (socket.request.headers.cookie) return next();
next(new Error('Authentication error'));
});
Event: 'connect'
socket
(Socket) socket connection with client
Fired upon a connection from client.
io.on('connection', (socket) => {
// ...
});
io.of('/admin').on('connection', (socket) => {
// ...
});
Event: 'connection'
Synonym of Event: 'connect'.
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
Flag: 'binary'
Specifies whether there is binary data in the emitted data. Increases performance when specified. Can be true
or false
.
io.binary(false).emit('an event', { some: 'data' });
Flag: 'local'
Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node (when the Redis adapter is used).
io.local.emit('an event', { some: 'data' });
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.
socket.id
- (String)
A unique identifier for the session, that comes from the underlying Client
.
socket.rooms
- (Object)
A hash of strings identifying the rooms this client is in, indexed by room name.
io.on('connection', (socket) => {
socket.join('room 237', () => {
let rooms = Object.keys(socket.rooms);
console.log(rooms); // [ <socket.id>, 'room 237' ]
});
});
socket.client
- (Client)
A reference to the underlying Client
object.
socket.conn
- (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.request
- (Request)
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
.
const cookie = require('cookie');
io.on('connection', (socket) => {
const cookies = cookie.parse(socket.request.headers.cookie || '');
});
socket.handshake
- (Object)
The handshake details:
{
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 object */
}
Usage:
io.use((socket, next) => {
let handshake = socket.handshake;
// ...
});
io.on('connection', (socket) => {
let handshake = socket.handshake;
// ...
});
socket.use(fn)
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 middleware callbacks are sent as special error
packets to clients.
io.on('connection', (socket) => {
socket.use((packet, next) => {
if (packet.doge === true) return next();
next(new Error('Not a doge error'));
});
});
socket.send([...args][, ack])
args
ack
(Function)- Returns
Socket
Sends a message
event. See socket.emit(eventName[, ...args][, ack]).
socket.emit(eventName[, ...args][, ack])
(overrides EventEmitter.emit
)
eventName
(String)args
ack
(Function)- Returns
Socket
Emits an event to the socket identified by the string name. Any other parameters can be included. All serializable datastructures are supported, including Buffer
.
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.
io.on('connection', (socket) => {
socket.emit('an event', { some: 'data' });
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
// the client code
// client.on('ferret', (name, fn) => {
// fn('woot');
// });
});
socket.on(eventName, callback)
(inherited from EventEmitter
)
eventName
(String)callback
(Function)- Returns
Socket
Register a new handler for the given event.
socket.on('news', (data) => {
console.log(data);
});
// with several arguments
socket.on('news', (arg1, arg2, arg3) => {
// ...
});
// or with acknowledgement
socket.on('news', (data, callback) => {
callback(0);
});
socket.once(eventName, listener)
socket.removeListener(eventName, listener)
socket.removeAllListeners([eventName])
socket.eventNames()
Inherited from EventEmitter
(along with other methods not mentioned here). See the Node.js documentation for the events module.
socket.join(room[, callback])
room
(String)callback
(Function)- Returns
Socket
for chaining
Adds the client to the room
, and fires optionally a callback with err
signature (if any).
io.on('connection', (socket) => {
socket.join('room 237', () => {
let rooms = Object.keys(socket.rooms);
console.log(rooms); // [ <socket.id>, 'room 237' ]
io.to('room 237').emit('a new user has joined the room'); // broadcast to everyone in the 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:
io.on('connection', (socket) => {
socket.on('say to someone', (id, msg) => {
// send a private message to the socket with the given id
socket.to(id).emit('my message', msg);
});
});
socket.join(rooms[, callback])
rooms
(Array)callback
(Function)- Returns
Socket
for chaining
Adds the client to the list of room, and fires optionally a callback with err
signature (if any).
io.on('connection', (socket) => {
socket.join(['room 237', 'room 238'], () => {
const rooms = Object.keys(socket.rooms);
console.log(rooms); // [ <socket.id>, 'room 237', 'room 238' ]
io.to('room 237').to('room 238').emit('a new user has joined the room'); // broadcast to everyone in both rooms
});
});
socket.leave(room[, callback])
room
(String)callback
(Function)- Returns
Socket
for chaining
Removes the client from room
, and fires optionally a callback with err
signature (if any).
io.on('connection', (socket) => {
socket.leave('room 237', () => {
io.to('room 237').emit(`user ${socket.id} has left the room`);
});
});
Rooms are left automatically upon disconnection.
socket.to(room)
room
(String)- Returns
Socket
for chaining
Sets a modifier for a subsequent event emission that the event will only be broadcasted to clients that have joined the given room
(the socket itself being excluded).
To emit to multiple rooms, you can call to
several times.
io.on('connection', (socket) => {
// to one room
socket.to('others').emit('an event', { some: 'data' });
// to multiple rooms
socket.to('room1').to('room2').emit('hello');
// a private message to another socket
socket.to(/* another socket id */).emit('hey');
// WARNING: `socket.to(socket.id).emit()` will NOT work, as it will send to everyone in the room
// named `socket.id` but the sender. Please use the classic `socket.emit()` instead.
});
Note: acknowledgements are not supported when broadcasting.
socket.in(room)
Synonym of socket.to(room).
socket.compress(value)
value
(Boolean) whether to following packet will be compressed- Returns
Socket
for chaining
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.
io.on('connection', (socket) => {
socket.compress(false).emit('uncompressed', "that's rough");
});
socket.disconnect(close)
close
(Boolean) whether to close the underlying connection- Returns
Socket
Disconnects this client. If value of close is true
, closes the underlying connection. Otherwise, it just disconnects the namespace.
io.on('connection', (socket) => {
setTimeout(() => socket.disconnect(true), 5000);
});
Flag: 'broadcast'
Sets a modifier for a subsequent event emission that the event data will only be broadcast to every sockets but the sender.
io.on('connection', (socket) => {
socket.broadcast.emit('an event', { some: 'data' }); // everyone gets it 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).
io.on('connection', (socket) => {
socket.volatile.emit('an event', { some: 'data' }); // the client may or may not receive it
});
Flag: 'binary'
Specifies whether there is binary data in the emitted data. Increases performance when specified. Can be true
or false
.
const io = require('socket.io')();
io.on('connection', (socket) => {
socket.binary(false).emit('an event', { some: 'data' }); // The data to send has no binary data
});
Event: 'disconnect'
reason
(String) the reason of the disconnection (either client or server-side)
Fired upon disconnection.
io.on('connection', (socket) => {
socket.on('disconnect', (reason) => {
// ...
});
});
Possible reasons:
Reason | Side | Description |
---|---|---|
transport error | Server Side | Transport error |
server namespace disconnect | Server Side | Server performs a socket.disconnect() |
client namespace disconnect | Client Side | Got disconnect packet from client |
ping timeout | Client Side | Client stopped responding to pings in the allowed amount of time (per the pingTimeout config setting) |
transport close | Client Side | Client stopped sending data |
Event: 'error'
error
(Object) error object
Fired when an error occurs.
io.on('connection', (socket) => {
socket.on('error', (error) => {
// ...
});
});
Event: 'disconnecting'
reason
(String) the reason of the disconnection (either client or server-side)
Fired when the client is going to be disconnected (but hasn't left its rooms
yet).
io.on('connection', (socket) => {
socket.on('disconnecting', (reason) => {
let rooms = Object.keys(socket.rooms);
// ...
});
});
These are reserved events (along with connect
, newListener
and removeListener
) which cannot be used as event names.
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.
client.conn
- (engine.Socket)
A reference to the underlying engine.io
Socket
connection.
client.request
- (Request)
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
.