This is a rough spec for reference. It is not a complete spec and may not be 100% accurate.
- Each
Schema
instance has aChangeTree
instance, which tracks changes. - Whenever a property is changed within a
Schema
instance, that change is cached inside itsChangeTree
. - Changes are tracked into separate categories: "all", "changes", and "filtered" (used to encode with
StateView
's).
There are two main types of encoding: the "encode all" and the "encode changes".
- "encode all" is used when a client joins a room, and the server sends the full state of the room.
- "encode changes" is used to encode all the pending changes.
- Each
Schema
instance holds a reference to its ownChangeTree
instance, which has a uniquerefId
. - The root structure has
refId
of0
. Schema
instances are encoded as a sequence ofindex
=>value
.MapSchema
instances have adynamicIndex
encoded sequentially as itsindex
, following by thevalue
(CollectionSchema
andSetSchema
are encoded in the same way asMapSchema
)- When encoding a child
Schema
structure, only itsrefId
is encoded. ArraySchema
instances are encoded as a sequence ofindex
+value
, whereindex
is the index of the array, andvalue
is the encoded value.- When using
StateView
:- On array of primitive types: Not possible to filter particular items. Either all items are encoded, or none.
- On array of
Schema
instances: Instead of encoding theindex
, therefId
is encoded instead.
- When using
This is the process of joining the room:
(The length of each message is part of the WebSocket message frame itself. This is not the case on WebTransport, which is currently experimental; C# does not have a solid implementation yet AFAIK)
Join Room Message {
Header (uint8) = 10,
ReconnectionTokenLength (uint8),
ReconnectionToken (string),
SerializerIdLength (uint8),
SerializerId (string),
Handshake Payload (...all bytes until the end of the message),
}
After receiving this message, the client sends back JOIN_ROOM
to confirm the connection, and the server sends back the full room state.
Room State Message {
Header (uint8) = 14,
Encoded State (...all bytes until the end of the message),
}
The format of the encoded state depends on the serializer being used. The default serializer is "schema"
, which is a binary format. The "schema"
serializer is the most efficient one, but it's not human-readable. The json
serializer is also available, but it's less efficient.