Architecture overview¶
At a lower level, request and message flow looks like this:
ASGI → Channels → Engine.IO transport consumers
→ Engine.IO core → Socket.IO → your handlers
Conceptually, this matches the Node.js reference layering:
Your code ↔ Socket.IO ↔ Engine.IO ↔ raw HTTP/WS
Transport flow¶
Concretely:
the ASGI server, such as Daphne or Uvicorn, receives HTTP/WebSocket connections;
Django Channels routes them to
SocketIOConsumer.as_asgi();the consumer dispatches HTTP scopes to the Engine.IO long-polling transport;
the consumer dispatches WebSocket scopes to the Engine.IO WebSocket transport;
the Engine.IO core handles query parameters such as
EIO=4andtransport=...;Engine.IO handles heartbeats, HTTP payload framing, WebSocket frames, and per-connection session state;
completed Engine.IO
messagepackets are passed to the Socket.IO layer;Socket.IO parses packets and calls your consumer event handlers.
Engine.IO layer¶
The Engine.IO implementation lives in sio.engineio and provides:
EngineIOSessionPer-connection state, including transport, queues, and heartbeats.
LongPollingConsumerChannels
AsyncHttpConsumerimplementing the HTTP long-polling transport.EngineIOWebSocketConsumerChannels
AsyncWebsocketConsumerfor the WebSocket transport and upgrade.EngineIOSocketApplication-facing wrapper around a session, used by Socket.IO.
sio.engineio.packetsHelpers to encode and decode Engine.IO packets and HTTP payloads.
Each Engine.IO connection is represented by one EngineIOSession and one
EngineIOSocket. The polling and WebSocket transports share the same session.
Socket.IO layer¶
The Socket.IO implementation lives in sio.socketio and provides:
SocketIOPacketIn-memory packet representation, including type, namespace, and data.
SocketIOParserConverts Engine.IO
messagepayloads into Socket.IO packets, including binary attachment handling and placeholder substitution.SocketIOServerManages namespaces, per-namespace sockets, room membership, and broadcasts.
NamespaceSocketRepresents one client in one namespace and exposes methods such as
emit,send,join,leave,leave_all, anddisconnect.
The server is configured once and used by all consumers. The singleton helper
sio.socketio.server.get_socketio_server installs SocketIOServer as the
Engine.IO application handler through set_engineio_app.
Consumer integration¶
sio.SocketIOConsumer glues everything together:
it creates and configures the global
SocketIOServeron first use;for each subclass, it registers a namespace;
it wires
connectanddisconnectmethods if present;it maps methods named
event_<name>to Socket.IO events named<name>;it exposes
as_asgi(), which returns an ASGI app that routes HTTP scopes toLongPollingConsumerand WebSocket scopes toEngineIOWebSocketConsumer.
You typically never touch the lower-level Engine.IO consumers directly. Mount
your SocketIOConsumer subclass in Channels routing.