Skip to main content

Realtime APIs

RealtimeNamespace is a globally available class that lets you build realtime, event-driven functions using the Socket.IO protocol. Clients connect via WebSocket and your function handles connection lifecycle events and custom events — with full support for rooms, broadcasting, and authentication.

A RealtimeNamespace instance is itself a function, so it can be used directly as your function's export:

const ns = new RealtimeNamespace('/chat');

ns.socket.on('$connect', function () {
console.log('Client connected:', ns.socket.id);
ns.socket.join('general');
});

ns.socket.on('message', function (data) {
ns.socket.to('general').emit('message', {
from: ns.socket.id,
text: data.text,
});
});

ns.socket.on('$disconnect', function (reason) {
console.log('Client disconnected:', ns.socket.id, reason);
});

module.exports = ns;

Creating a RealtimeNamespace

const ns = new RealtimeNamespace('/chat');

The argument is the namespace path. This must match the namespace path you configure in the admin UI under API Gateway → Realtime. RealtimeNamespace is available as a global — no require() call is necessary.

const ns = new RealtimeNamespace();

You can omit the namespace path if your function is set as a handler of a namespace in API Gateway → Realtime.

A RealtimeNamespace instance doubles as a request handler. When the gateway dispatches a socket event, it arrives as an internal HTTP request that ns handles automatically. For non-socket requests, it responds with 404 or passes to next() if used as middleware.

Event Handlers

Register handlers on ns.socket to respond to socket events. Inside a handler, this refers to the RealtimeNamespace instance and this.socket gives you access to the current socket.

ns.socket.on(event, handler)

Register a handler for a named event. Returns the socket for chaining.

ns.socket.on('$connect', function () {
console.log('New connection:', ns.socket.id);
});

ns.socket.on('chatMessage', function (data) {
console.log('Received:', data);
});

ns.socket.once(event, handler)

It is basically alias of ns.socket.on(event, handler). In serverless environment, everything is stateless. Therefore, handler cannot be unregistered after first execution.

Reserved Events

Two event names have special meaning:

EventWhen it firesHandler receives
$connectA client connects to the namespace(nothing)
$disconnectA client disconnectsreason (string)

All other event names are custom events defined by your application. Each custom event handler receives the data the client sent as its arguments.

ns.socket.on('$connect', function () {
// No arguments — use ns.socket.handshake for connection metadata
});

ns.socket.on('$disconnect', function (reason) {
console.log('Disconnected because:', reason);
// reason: 'transport close', 'client namespace disconnect', etc.
});

ns.socket.on('move', function (data) {
// data is whatever the client sent: { x: 10, y: 20 }
});

Socket Properties

Inside an event handler, ns.socket is automatically hydrated with the current connection's details.

ns.socket.id

The unique identifier for the connected socket.

ns.socket.on('$connect', function () {
console.log(ns.socket.id); // e.g. 'abc123xyz'
});

ns.socket.rooms

A Set of room names the socket has joined. Every socket automatically joins a room matching its own id.

ns.socket.on('$connect', function () {
console.log(ns.socket.rooms); // Set { 'abc123xyz' }
ns.socket.join('lobby');
// rooms would be Set { 'abc123xyz', 'lobby' } on next event
});

ns.socket.handshake

Metadata from the initial connection handshake:

ns.socket.on('$connect', function () {
const { headers, query, auth, address, time } = ns.socket.handshake;

console.log(headers['user-agent']); // Client user-agent
console.log(query.token); // Query string params
console.log(auth.userId); // Auth payload from client
console.log(address); // Client IP address
});
PropertyTypeDescription
headersobjectHTTP headers from the initial handshake request
queryobjectQuery string parameters
authobjectAuthentication payload sent by the client
addressstringClient's IP address
timestringTimestamp of the connection

ns.socket.data

An arbitrary object for storing per-socket state. Persists for the lifetime of the connection (in-memory only). Highly not recommended to use as the serverless function is stateless.

ns.socket.on('$connect', function () {
ns.socket.data.username = ns.socket.handshake.auth.username;
});

ns.socket.on('message', function (data) {
console.log(ns.socket.data.username, 'says:', data.text);
});

ns.socket.connected

Boolean indicating whether the socket is currently connected.

ns.socket.on('$disconnect', function (reason) {
console.log(ns.socket.connected); // false
});

Socket Methods

ns.socket.emit(event, ...args)

Send an event directly to this socket.

ns.socket.on('$connect', function () {
ns.socket.emit('welcome', { message: 'Hello!' });
});

Returns: Promise<void>

ns.socket.join(room)

Add this socket to a room.

ns.socket.on('joinRoom', function (data) {
ns.socket.join(data.room);
ns.socket.emit('joined', { room: data.room });
});

Returns: Promise<void>

ns.socket.leave(room)

Remove this socket from a room.

ns.socket.on('leaveRoom', function (data) {
ns.socket.leave(data.room);
});

Returns: Promise<void>

ns.socket.disconnect()

Force-disconnect this socket from the server.

ns.socket.on('ban', function () {
ns.socket.emit('banned', { reason: 'Violation' });
ns.socket.disconnect();
});

Returns: Promise<void>

ns.socket.to(room).emit(event, ...args)

Broadcast an event to all sockets in a room (excluding the sender).

ns.socket.on('message', function (data) {
ns.socket.to('general').emit('message', {
from: ns.socket.id,
text: data.text,
});
});

ns.socket.broadcast.emit(event, ...args)

Broadcast an event to all connected sockets in the namespace (excluding the sender).

ns.socket.on('announcement', function (data) {
ns.socket.broadcast.emit('announcement', data);
});

ns.socket.except(room).emit(event, ...args)

Broadcast to all sockets in the namespace except those in the specified room.

ns.socket.on('alert', function (data) {
ns.socket.except('muted').emit('alert', data);
});

Namespace Methods

These methods operate at the namespace level — they are not scoped to the current socket.

ns.to(room).emit(event, ...args)

Broadcast to all sockets in a room (including the sender, unlike socket.to()).

ns.socket.on('serverMessage', function (data) {
ns.to('general').emit('serverMessage', data);
});

ns.except(room).emit(event, ...args)

Broadcast to all sockets in the namespace except those in the specified room.

ns.socket.on('maintenance', function () {
ns.except('admins').emit('maintenance', { message: 'Going offline soon' });
});

ns.emit(event, ...args)

Broadcast to every socket in the namespace.

ns.socket.on('globalAlert', function (data) {
ns.emit('globalAlert', data);
});

Note: ns.join(), ns.leave(), and ns.broadcast are not available at the namespace level — use ns.socket.join(), ns.socket.leave(), and ns.socket.broadcast inside an event handler instead.

Broadcast Chaining

The to() and except() methods return a BroadcastOperator that supports chaining for fine-grained targeting.

Multi-room broadcast

// Send to sockets in room1 OR room2
ns.socket.to('room1').to('room2').emit('update', data);

Include and exclude

// Send to room1, but not to anyone also in room2
ns.socket.to('room1').except('room2').emit('update', data);

Namespace-level chaining

// Namespace broadcast to two rooms, excluding a third
ns.to('vip').to('premium').except('banned').emit('offer', { discount: 20 });

Complete Example

A group chat function with rooms, typing indicators, and private messages:

const ns = new RealtimeNamespace('/chat');

ns.socket.on('$connect', function () {
const username = ns.socket.handshake.auth.username || 'Anonymous';
ns.socket.data.username = username;
ns.socket.join('lobby');
ns.socket.emit('welcome', { message: `Hello, ${username}!` });
ns.socket.to('lobby').emit('userJoined', { username });
});

ns.socket.on('joinRoom', function (data) {
ns.socket.leave('lobby');
ns.socket.join(data.room);
ns.socket.to(data.room).emit('userJoined', {
username: ns.socket.data.username,
});
});

ns.socket.on('message', function (data) {
ns.socket.to(data.room || 'lobby').emit('message', {
from: ns.socket.data.username,
text: data.text,
timestamp: Date.now(),
});
});

ns.socket.on('typing', function (data) {
ns.socket.to(data.room || 'lobby').emit('typing', {
username: ns.socket.data.username,
});
});

ns.socket.on('privateMessage', function (data) {
ns.socket.emit('privateMessage', {
from: ns.socket.data.username,
text: data.text,
});
// Also send to the target socket directly
ns.to(data.targetSocketId).emit('privateMessage', {
from: ns.socket.data.username,
text: data.text,
});
});

ns.socket.on('$disconnect', function (reason) {
ns.emit('userLeft', {
username: ns.socket.data.username,
reason,
});
});

module.exports = ns;

Reference

RealtimeNamespace

MethodSignatureDescription
constructornew RealtimeNamespace(namespacePath)Create a new namespace handler
to.to(room)Target a room (returns BroadcastOperator)
in.in(room)Alias for to()
except.except(room)Exclude a room (returns BroadcastOperator)
emit.emit(event, ...args)Broadcast to entire namespace

Socket (ns.socket)

Method / PropertySignatureDescription
idstringUnique socket identifier
roomsSet<string>Rooms this socket belongs to
handshakeobjectConnection metadata (headers, query, auth, address, time)
dataobjectArbitrary per-socket storage
connectedbooleanWhether the socket is connected
on.on(event, handler)Register an event handler
once.once(event, handler)Register a one-time handler
emit.emit(event, ...args)Send to this socket
join.join(room)Join a room
leave.leave(room)Leave a room
disconnect.disconnect()Force-disconnect this socket
to.to(room)Target a room (returns BroadcastOperator)
in.in(room)Alias for to()
except.except(room)Exclude a room (returns BroadcastOperator)
broadcast.broadcastBroadcastOperator excluding this socket

BroadcastOperator

MethodSignatureDescription
to.to(room)Add a room to target (chainable)
in.in(room)Alias for to()
except.except(room)Add a room to exclude (chainable)
emit.emit(event, ...args)Send the event to matching sockets