Streams
Streams are a powerful feature that gives you full control over LayerG's internal real-time routing and delivery.
LayerG's real-time message routing and delivery subsystem is organized into streams. Streams tie together clients interested in certain message types and allow LayerG's internal components to deliver messages to relevant users.
Clients may receive messages and data from streams, but are not allowed to directly join, leave, or send data themselves. These functions are only available in the server code runtime.
All of the higher-level real-time features in the server (chat channels, multiplayer, notifications, etc.) are built as features on top of streams. Understanding and using streams are not necessary to use these features.
Structure of a stream
Streams are defined by two components: a stream identifier and presence list.
Stream identifier
All streams have their own unique id. This is used to place users onto streams and locate streams for message delivery. A stream id has 4 fields:
- Mode marks the type of stream. For example chat channels have different names but the same mode. Stream modes must be in the range
0-255
. - Subject contains a primary stream subject usually a user id. Mode is the only required field.
- Subcontext is a secondary id. Used when a stream is scoped to a pair of users or groups like with direct chat between two users.
- Label stores a string which could be meta-information. A chat room created by name uses the label field.
There are several built-in streams available. Note that the mode
values used by these streams are reserved cannot be used for custom streams.
Presence list
Streams are a way to address a set of online users and deliver messages to them. Each stream maintains a list of presences that uniquely identify a user with the socket they’re connected on. When the server sends a message to a stream it will be delivered to all clients identified by the presences.
Persistence and message history
Presences may be marked with an optional persistence flag. The server can observe this flag when handling messages delivered to a stream to decide whether the message data should be stored in the database. The real-time chat feature uses this flag to decide if messages should be stored so clients can request message history.
Hidden stream members
Streams generate presence events that notify all users currently in the stream when a new user joins or an existing user leaves the stream. Presences may be marked with an optional hidden flag. When this is set to true the server will not generate presence events when this user joins or leaves.
Hidden presences are still full stream members so they do receive data and presence events as normal.
Receiving stream data
Clients can register an event handler to consume stream data objects when received over the socket. The handler function will be called once for each stream data message.
Receiving stream presence events
When a new presence joins a stream or an existing presence leaves the server will broadcast presence events to all users currently on the stream.
Hidden presences do not generate presence events and won’t appear in results received by this event handler.
Join a stream
The server can place users on any number of streams. To add a user to a stream the server needs the user’s ID, the unique session ID of the user’s current session, and information about the stream they should be placed on.
As an example we can register an RPC function that will place the user that calls it on a custom stream.
If this user+session is already a member of the stream the operation will be a no-op.
Leave a stream
Leaving streams is also controlled by the server. To remove a user from a stream the server needs the user’s ID, the unique session ID of the user’s current session, and information about the stream they should be removed from.
As an example we can register an RPC function that will remove the user that calls it from the custom stream.
If this user+session is not a member of the stream the operation will be a no-op.
Just like chat channels and real-time multiplayer matches when a client disconnects it is automatically removed from any streams it was part of.
Send data to a stream
The server can send data to a stream through a function call. The message will be delivered to all users present on the stream. The message payload sent to a stream can be any string, but a structured format such as JSON is recommended.
If the stream is empty the operation will be a no-op.
Close a stream
Closing a stream removes all presences currently on it. It can be useful to explicitly close a stream and enable the server to reclaim resources more quickly.
Counting stream presences
The server can peek at the presences on a stream to obtain a quick count without processing the full list of stream presences.
Listing stream presences
A list of stream presence contains every user currently online and connected to that stream, along with information about the session ID they are connected through and additional metadata.
Check a stream presence
If only a single user is needed the server can check if that user is present on a stream and retrieve their presence and metadata.
As an example we can register an RPC function that will check if the user that calls it is active on a custom stream.
Built-in streams
The server’s real-time features such as chat channels, multiplayer, parties, and notifications are built on top of streams.
By understanding the structure of these streams the code runtime can authoritatively change any of these features.
Stream mode
values must be in the range 0-255
, but note that the values used by these built-in streams are reserved and cannot be used by custom streams.
Stream | Mode | Subject | Subcontext | Label | Information |
---|---|---|---|---|---|
Notifications | 0 | User ID | - | - | Controls the delivery of in-app notifications to connected users. |
Status | 1 | User ID | - | - | Controls the status feature and broadcasting updates to friends. |
Chat Channel | 2 | - | - | “channel name” | Membership to a chat channel. |
Group Chat | 3 | Group ID | - | - | A group’s private chat channel. |
Direct Message | 4 | User ID | User ID | - | A private direct message conversation between two users. |
Relayed Match | 5 | Match ID | - | - | Membership and message routing for a relayed real-time multiplayer match. |
Authoritative Match | 6 | Match ID | - | “Layerg node name” | Membership and message routing for an authoritative real-time multiplayer match. |
Party | 7 | Party ID | - | - | Membership and message routing for a party. |
Using these stream identifiers with the functions described above allows full control over the internal behavior of these features.
Example: Kick a user from a chat channel
This code removes a user from a chat channel. If the user has more than one session connected to the channel only the specified one will be removed.
Example: Stop receiving notifications
By calling this RPC function a user can “silence” their notifications. Even if they remain online they will no longer receive real-time delivery of any in-app notifications.