Broadcast Groups
Named groups with explicit membership, roles, metadata, and lifecycle hooks. Like topics but with access control - you decide who can join, what role they have, and what happens when the group fills up or closes.
Setup
// src/lib/server/lobby.js
import { createGroup } from 'svelte-adapter-uws/plugins/groups';
export const lobby = createGroup('lobby', {
maxMembers: 50,
meta: { game: 'chess' },
onJoin: (ws, role) => console.log('joined as', role),
onFull: (ws, role) => {
// optionally notify the rejected client
}
}); Options
| Option | Default | Description |
|---|---|---|
maxMembers | Infinity | Maximum members |
meta | {} | Initial metadata (shallow-copied) |
onJoin | - | (ws, role) → void |
onLeave | - | (ws, role) → void |
onFull | - | (ws, role) → void |
onClose | - | () → void |
Roles: 'member' (default), 'admin', 'viewer'.
Server usage
Use the hooks helper for zero-config access control. The subscribe hook intercepts the internal __group:lobby topic, calls join(), and blocks the subscription if the group is full or closed. The close hook calls leave().
// src/hooks.ws.js
import { lobby } from '$lib/server/lobby';
export const { subscribe, unsubscribe, close } = lobby.hooks; If you need custom logic (role selection, auth gating), wrap the hook:
// src/hooks.ws.js
import { lobby } from '$lib/server/lobby';
export function subscribe(ws, topic, ctx) {
if (topic === '__group:lobby') {
const role = ws.getUserData().isAdmin ? 'admin' : 'member';
return lobby.join(ws, ctx.platform, role) ? undefined : false;
}
lobby.hooks.subscribe(ws, topic, ctx);
}
export const { unsubscribe, close } = lobby.hooks; Publish to group members:
// Broadcast to everyone
lobby.publish(platform, 'chat', { text: 'hello' });
// Broadcast only to admins
lobby.publish(platform, 'admin-alert', { msg: 'new report' }, 'admin'); Server API
| Method | Description |
|---|---|
group.join(ws, platform, role?) | Add member. Returns true or false if full/closed |
group.leave(ws, platform) | Remove member |
group.publish(platform, event, data, role?) | Broadcast (optionally filtered by role) |
group.send(platform, ws, event, data) | Send to one member (throws if not a member) |
group.members() | Array of { ws, role } |
group.count() | Member count |
group.has(ws) | Check membership |
group.close(platform) | Dissolve group, notify everyone |
group.name | Group name (read-only) |
group.meta | Metadata (get/set) |
group.hooks | Ready-made { subscribe, unsubscribe, close } hooks with access control |
Client usage
<script>
import { group } from 'svelte-adapter-uws/plugins/groups/client';
const lobby = group('lobby');
const members = lobby.members;
</script>
<p>{$members.length} members</p> The client store exposes two reactive values: the main store for events ($lobby - latest message) and .members for the live member list. The member list updates automatically on join, leave, and close events - no polling needed.
Limitations
- In-memory. Group state lives in the process. In cluster mode, each worker manages its own groups independently.
- No persistence. Groups are lost on restart. If you need durable rooms, store membership in a database and rebuild on start.
- Role-filtered publish uses
send(). When filtering by role, the plugin iterates members and sends individually instead of using the topic broadcast. Fine for typical group sizes, but O(n) with member count.
Was this page helpful?