Skip to main content

Quick Start: Server

This walk-through builds a SignalR hub in Python and serves it over WebSocket.

1. Define a hub

A hub is a subclass of Hub. Every public method becomes invocable by clients. Return values are sent back as results; methods that yield become streaming methods.

import asyncio

from aiosignalr.server import Hub, SignalRServer


class ChatHub(Hub):
async def on_connected(self) -> None:
await self.clients.all_.send(
"message", f"User {self.context.connection_id} joined"
)

async def echo(self, text: str) -> str:
return text

async def counter(self, n: int):
for i in range(n):
yield i
await asyncio.sleep(0.01)


async def main() -> None:
server = SignalRServer(ChatHub)
await server.serve("127.0.0.1", 8080, path="/hub")


asyncio.run(main())

Special parameters

You can inject connection context and cancellation into a method by naming the parameter:

  • context / hub_context → the HubContext with connection_id, headers and query string.
  • cancellation_token / cancellationToken → an asyncio.Event that is set when the client cancels the invocation.
class MyHub(Hub):
async def slow_operation(self, n: int, cancellation_token: Any = None) -> int:
for i in range(n):
await asyncio.sleep(0.05)
if cancellation_token is not None and cancellation_token.is_set():
return -1
return n

2. Choose a host

SignalRServer.serve() runs a standalone aiohttp application:

await server.serve("127.0.0.1", 8080, path="/hub")

You can also mount the server inside an existing ASGI application (uvicorn / FastAPI):

app = server.asgi_app(path="/hub")
# pass `app` to uvicorn.run(app, ...) or FastAPI

See Hosting for details.

3. Connect a client

Now point any SignalR client at the hub. With aiosignalr:

import asyncio

from aiosignalr.client import HubConnection


async def main() -> None:
conn = HubConnection()
conn.on("message", lambda text: print("server says:", text))
await conn.start("http://127.0.0.1:8080/hub")

print(await conn.invoke("echo", "ping")) # "ping"
async for item in await conn.stream("counter", 3):
print("counter:", item)

await conn.stop()


asyncio.run(main())

Next steps