Clients, Groups & Users
The server sends messages to clients through self.clients, a typed client
proxy, and tracks groups through self.groups.
Sending to everyone
class BroadcastHub(Hub):
async def notify_all(self, text: str) -> None:
await self.clients.all_.send("broadcast", text)
clients.all_ targets every connected client, optionally excluding some:
await self.clients.all_.send("broadcast", text, excluded=frozenset({connection_id}))
clients.others is shorthand for "everyone except the caller":
await self.clients.others.send("broadcast", text)
Sending to specific clients
# One connection
await self.clients.connection(connection_id).send("target", *args)
# Several connections
await self.clients.connections((id_a, id_b)).send("target", *args)
Sending to groups
Groups are named sets of connections managed by the hub:
class RoomHub(Hub):
async def join_room(self, room: str) -> None:
await self.groups.add(room)
async def leave_room(self, room: str) -> None:
await self.groups.remove(room)
async def room_chat(self, room: str, text: str) -> None:
await self.clients.group(room).send("chat", text)
groups.add(name)/groups.remove(name)mutate the caller's membership.clients.group(name).send(...)broadcasts to the group.- Membership is removed automatically when a connection disconnects.
Sending to users
If connections carry a user id, you can target them:
await self.clients.user(user_id).send("target", *args)
await self.clients.users((uid_a, uid_b)).send("target", *args)
The user_id is read from ctx.context.user_id. The default lifetime manager
matches by that value.
Type of send targets
| Proxy | Target |
|---|---|
all_ | Every connected client |
others | Every client except the caller |
connection(id) | A single connection |
connections(ids) | Several connections |
group(name) | Members of a group |
groups(names) | Members of several groups |
user(id) | Connections with the given user id |
users(ids) | Connections with the given user ids |
Each proxy returns a client handle exposing send(method, *args).
Broadcast encoding
For efficiency, clients.all_.send(...) serializes the message once per
protocol and reuses the encoded bytes for every recipient connection (see
DefaultHubLifetimeManager._send). When stateful reconnect is enabled, the
encoded bytes are also fed through each recipient's message buffer so they are
replayed if that client was disconnected at send time.