on_connect(req, ws, **params) -> bool | None- Inspect headers and seed
self.state; returnFalseto reject the connection. The router runsafter_connecthooks before it callsaccept(). Withreceive_loop=True, it then begins receiving frames; with the defaultFalse, the application owns reception. Ifon_connect()sends a frame itself, callawait ws.accept()first. on_disconnect(ws, close_code) -> None- With
WebSocketRouter(receive_loop=True), afteron_connectpermits the session, the router runsbefore_disconnecthooks and attempts this callback once, including failure inafter_connectoraccept. The code is the peer's code, or1006when it is missing or setup fails. Cancellation before cleanup starts closes with1001and propagates. If cancellation interrupts a peer-disconnect callback already in progress, it is not retried and retains the peer code, while the socket closes with1001. Unexpected receive or handler failures close with1011and propagate the original exception. Rejected connections and failedon_connectcalls do not run this lifecycle. With the defaultreceive_loop=False, the application owns receive and cleanup. - With
receive_loop=True, the router passes values returned byws.receive_media()toWebSocketResource.dispatch()in order until the peer disconnects. Falcon may decode those values unless raw-frame media is enabled for the app.
For an attached router, attach() installs pass-through TEXT and BINARY
deserializers in the application's shared ws_options.media_handlers mapping.
For a manually mounted router, call configure_raw_frame_media(app) before
Falcon constructs WebSockets. Both configure all WebSocket routes on the app,
warn when replacing customized inbound handlers, and preserve the configured
outgoing serializers. Falcon's default handlers decode input when neither entry
point has enabled raw-frame handling.
self.state- Dict-like proxy shared across all resources in the same connection chain.
- Override via
get_child_context()to supply a custom state store (e.g., Redis-backed proxy).
Nested resources
class Parent(WebSocketResource):
def __init__(self):
self.state["parent_ready"] = True
self.add_subroute("child/{item}", Child)
def get_child_context(self):
return {"project": "acme"} # merged into child kwargs
class Child(WebSocketResource):
def __init__(self, project: str):
self.project = project
async def on_connect(self, req, ws, item: str) -> bool:
self.state["child_item"] = item
return False
- Path params flow into each resource; parent-provided context merges with params for the next child.
- State defaults to a shared proxy unless overridden in
get_child_context().