Skip to content

Custom Namespaces

eric edited this page Jul 18, 2026 · 1 revision

Custom Namespaces

Since 0.15.0 the broker can host additional socket.io namespaces from operator-supplied modules — new realtime surfaces (collaboration rooms, signaling buses, device channels) without touching tyo-mq core. The same pattern as the custom storage backend: a module path in settings.

{
  "namespaces": {
    "/collab": { "module": "./namespaces/collab.js", "options": { "max_rooms": 100 } },
    "/fanout": "@myorg/mq-ns-fanout"
  }
}

Names are normalized ("collab"/collab); a bare string is shorthand for { "module": ... }. / and /remote are reserved and cannot be overridden.

The module contract

// module.exports = function attach(io, options, context) -> api | undefined
module.exports = function attach(io, options, context) {
    var nsp = io.of(context.name);           // claim your namespace
    nsp.on('connection', function (socket) {
        socket.on('hello', function (data) {
            var limits = context.getOptions(); // live, hot-reloaded options
            socket.emit('hello_reply', { ok: true });
        });
    });
    return { /* anything here surfaces as server.namespaces['/collab'] */ };
};

context is deliberately minimal:

Field Purpose
name the normalized namespace name (/collab)
logger the server's logger
getOptions() the namespace's live options block — settings changes apply without re-attach
getSettings(key) read-only access to any top-level server setting

The bundled Remote Namespace (lib/remote-namespace.js) implements this exact contract and is the reference implementation — tickets, rooms, a config-driven relay, and a returned API (issueTicket, getSession, listSessions).

Lifecycle and safety

  • Namespaces attach at server create() and live on settings reload when a new entry appears; removing one requires a restart (socket.io cannot cleanly detach a namespace with live sockets).
  • A module that fails to load or throws at attach is logged and skipped — a broken namespace can never take the broker down, and the other namespaces still attach.
  • Module paths resolve relative to the server's working directory (or absolute); they are operator-controlled configuration, the same trust level as the custom storage backend's storage_options.module.
  • Returned APIs are reachable as server.namespaces['/name']; the get management command lists every attached namespace and its module (/remote shows as built-in) — see Management Commands.

When to use what

Need Use
New event names inside a /remote session nothing — the relay catch-all already forwards them (Remote Namespace)
Restricting/extending /remote relay rules remote.relay settings block
A whole new realtime surface with its own auth/rooms a custom namespace module (this page)
Plain pub/sub between services the main namespace — producers/consumers, no module needed

Clone this wiki locally