Routers¶
fastsio provides a lightweight router, RouterSIO, to organize your Socket.IO
handlers in a familiar way.
Basic usage¶
from fastsio import AsyncServer, RouterSIO
sio = AsyncServer()
router = RouterSIO(namespace="/chat")
@router.on("message")
async def handle_message(sid: SocketID, data: Data):
await sio.emit("message", data, room=sid, namespace="/chat")
# Attach to server
sio.add_router(router)
Decorators¶
router.on(event, namespace=None): register a handler for an explicit event name.@router.event(namespace=None): shorthand using the function name as event.@router.exception_handler(ExceptionClass): handle exceptions raised by handlers registered through this router.
Multiple routers¶
You can structure your code into multiple routers and attach them:
router_chat = RouterSIO(namespace="/chat")
router_admin = RouterSIO(namespace="/admin")
sio.add_routers(router_chat, router_admin)
Nested routers¶
Routers can include other routers. The parent router namespace is prefixed to all handlers registered in the child router:
api_router = RouterSIO(namespace="/api")
chat_router = RouterSIO(namespace="/chat")
@chat_router.on("message")
async def handle_message(sid: SocketID, data: Data):
...
api_router.add_router(chat_router)
sio.add_router(api_router) # registers "message" on "/api/chat"
Explicit namespaces on child handlers are also prefixed by the parent router:
@chat_router.on("connect", namespace="/room")
async def handle_connect(sid: SocketID, environ: Environ):
...
api_router.add_router(chat_router)
sio.add_router(api_router) # registers "connect" on "/api/room"
Router Exception Handlers¶
Routers can define exception handlers that apply only to handlers registered through that router:
class RoomClosed(Exception):
pass
chat_router = RouterSIO(namespace="/chat")
@chat_router.exception_handler(RoomClosed)
async def room_closed_handler(
sio: AsyncServer,
sid: SocketID,
exc: RoomClosed,
):
await sio.emit("error", {"message": "room closed"}, to=sid, namespace="/chat")
@chat_router.on("message")
async def message(sid: SocketID, data: Data):
raise RoomClosed()
Router exception handlers take precedence over server-level exception handlers. Nested routers inherit handlers from parent routers, and child routers can override them by registering their own handler for the same exception class.
Interplay with class-based namespaces¶
Routers register function-based handlers. If you also use class-based namespaces,
attach them to the router via router.register_namespace(ns_instance) and then
sio.add_router(router).