Skip to Content
Game ServerReal-time Messaging

Real-time Messaging

Send a message to one user or broadcast it to a group, at global or room scope.

Messaging is fire-and-forget pub/sub: a message reaches whoever is subscribed to that channel at the moment it is published. There is no acknowledgement, no retry and no replay, so a client that is disconnected, still connecting, or not yet subscribed simply misses it. Anything a player must not miss belongs in state ($global / $room), which they read on (re)connect — use messages for the transient layer on top.

Server API

Every message carries a type string, which is what clients subscribe to.

  • $global.broadcastToAll(type: string, message: any) — every connected user
  • $global.sendMessageToUser(type: string, account: string, message: any) — one user, wherever they are
  • $room.broadcastToRoom(type: string, message: any) — every user in the caller’s room
  • $room.sendMessageToUser(type: string, account: string, message: any) — one user in the caller’s room

Client API

  • server.onGlobalMessage(type, (message) => {})
  • server.onRoomMessage(roomId, type, (message) => {})

Both return an unsubscribe function. Call them from useEffect and return it — listeners are not deduplicated, so a subscribe in the render body registers another one on every render and each message is then handled repeatedly. Two things the SDK does not do for you:

  • Subscriptions are not restored after a reconnect. Keying the effect on connected / rsConnected, as in the example below, re-subscribes.
  • onRoomMessage needs a joined room. Before the Room Server connection is up the subscribe is dropped and the callback never fires — gate it on rsConnected and a real currentRoomId.

Example: Real-time Chat

server/src/server.ts
export class Server { async sendGlobalChat(message) { await $global.broadcastToAll("GLOBAL_CHAT", { sender: $sender.account, text: message, timestamp: Date.now(), }); } // No roomId parameter: $room already targets the caller's room. async sendRoomChat(message) { await $room.broadcastToRoom("ROOM_CHAT", { sender: $sender.account, text: message, timestamp: Date.now(), }); } }
Last updated on