36 changed files with 138 additions and 16 deletions
@ -0,0 +1,11 @@ |
|||||
|
import fastsio |
||||
|
from .routers import router |
||||
|
|
||||
|
sio = fastsio.AsyncServer( |
||||
|
async_mode="asgi", |
||||
|
cors_allowed_origins=None, |
||||
|
) |
||||
|
|
||||
|
# added all routers |
||||
|
sio.add_router(router=router) |
||||
|
|
@ -0,0 +1,16 @@ |
|||||
|
from fastsio import RouterSIO |
||||
|
|
||||
|
router = RouterSIO(namespace="/app") |
||||
|
|
||||
|
@router.on("connect", namespace="/room") # override router namespace |
||||
|
async def on_connect(sid, environ): |
||||
|
print("connect ", sid) |
||||
|
|
||||
|
@router.on("disconnect") |
||||
|
async def on_disconnect(sid): |
||||
|
print("disconnect ", sid) |
||||
|
|
||||
|
@router.on("message") |
||||
|
async def on_message(sid, data): |
||||
|
print("message ", data) |
||||
|
|
@ -0,0 +1,85 @@ |
|||||
|
from typing import Any, Callable, Dict, List, Optional, Tuple |
||||
|
|
||||
|
from . import base_namespace |
||||
|
|
||||
|
|
||||
|
class RouterSIO: |
||||
|
"""A lightweight router for organizing Socket.IO event handlers. |
||||
|
|
||||
|
This provides a FastAPI-like developer experience for grouping and |
||||
|
including handlers. Handlers registered on the router can later be |
||||
|
attached to a server via ``sio.add_router(router)``. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
router = RouterSIO(namespace="/chat") |
||||
|
|
||||
|
@router.on("message") |
||||
|
async def handle_message(sid: str, data: Any): |
||||
|
... |
||||
|
|
||||
|
sio.add_router(router) |
||||
|
""" |
||||
|
|
||||
|
def __init__(self, namespace: Optional[str] = None) -> None: |
||||
|
# Default namespace applied when not provided explicitly in .on()/@event |
||||
|
self.default_namespace: str = namespace or "/" |
||||
|
# Decorator-based function handlers: {namespace: {event: handler}} |
||||
|
self.handlers: Dict[str, Dict[str, Callable[..., Any]]] = {} |
||||
|
# Class-based namespace handlers to be registered on the server |
||||
|
self._namespace_handlers: List[base_namespace.BaseServerNamespace] = [] |
||||
|
|
||||
|
# Public API mirrors Server.on |
||||
|
def on( |
||||
|
self, |
||||
|
event: str, |
||||
|
handler: Optional[Callable[..., Any]] = None, |
||||
|
namespace: Optional[str] = None, |
||||
|
) -> Callable[[Callable[..., Any]], Callable[..., Any]]: |
||||
|
ns = namespace or self.default_namespace |
||||
|
|
||||
|
def set_handler(h: Callable[..., Any]) -> Callable[..., Any]: |
||||
|
if ns not in self.handlers: |
||||
|
self.handlers[ns] = {} |
||||
|
self.handlers[ns][event] = h |
||||
|
return h |
||||
|
|
||||
|
if handler is None: |
||||
|
return set_handler |
||||
|
set_handler(handler) |
||||
|
return set_handler |
||||
|
|
||||
|
# Convenience decorator mirrors Server.event |
||||
|
def event(self, *args: Any, **kwargs: Any) -> Callable[[Callable[..., Any]], Callable[..., Any]]: |
||||
|
if len(args) == 1 and len(kwargs) == 0 and callable(args[0]): |
||||
|
# invoked without arguments: @router.event |
||||
|
return self.on(args[0].__name__)(args[0]) |
||||
|
|
||||
|
# invoked with arguments: @router.event(namespace="...") |
||||
|
def set_handler(h: Callable[..., Any]) -> Callable[..., Any]: |
||||
|
return self.on(h.__name__, *args, **kwargs)(h) |
||||
|
|
||||
|
return set_handler |
||||
|
|
||||
|
def register_namespace(self, namespace_handler: base_namespace.BaseServerNamespace) -> None: |
||||
|
"""Queue a class-based namespace handler for registration. |
||||
|
|
||||
|
The actual registration occurs when the router is attached to a server |
||||
|
via ``sio.add_router(router)``. |
||||
|
""" |
||||
|
if not isinstance(namespace_handler, base_namespace.BaseServerNamespace): # type: ignore[redundant-expr] |
||||
|
raise ValueError("Not a namespace instance") |
||||
|
self._namespace_handlers.append(namespace_handler) |
||||
|
|
||||
|
# Internal helpers used by the server when attaching the router |
||||
|
def iter_function_handlers(self) -> List[Tuple[str, str, Callable[..., Any]]]: |
||||
|
out: List[Tuple[str, str, Callable[..., Any]]] = [] |
||||
|
for ns, events in self.handlers.items(): |
||||
|
for event, handler in events.items(): |
||||
|
out.append((ns, event, handler)) |
||||
|
return out |
||||
|
|
||||
|
def iter_namespace_handlers(self) -> List[base_namespace.BaseServerNamespace]: |
||||
|
return list(self._namespace_handlers) |
||||
|
|
||||
|
|
Loading…
Reference in new issue