Skip to main content

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.

StreamModeSubjectSubcontextLabelInformation
Notifications0User ID--Controls the delivery of in-app notifications to connected users.
Status1User ID--Controls the status feature and broadcasting updates to friends.
Chat Channel2--“channel name”Membership to a chat channel.
Group Chat3Group ID--A group’s private chat channel.
Direct Message4User IDUser ID-A private direct message conversation between two users.
Relayed Match5Match ID--Membership and message routing for a relayed real-time multiplayer match.
Authoritative Match6Match ID-“Layerg node name”Membership and message routing for an authoritative real-time multiplayer match.
Party7Party 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.