Contributors
Websocket Transport

Websocket Transport

The websocket transport is one of the island messaging transports supported by the Decentraland comms protocol. Clients should use it when they receive an appropriate connection string from their realm’s Archipelago service, or if it’s indiciated as a fixed transport.

In the context of the websocket transport, an island is referred to as a room. Either name indicates the same thing: a group of nearby players that exchange updates and chat.

Connection strings begin with the ws-room: prefix, followed by a wss:// URI for the specific room. They look like this:

ws-room:wss://comms.example.com/rooms/<room-id>

In the abscence of an explicit protocol for the websocket URI, wss:// is assumed.

Connecting #

The transport uses the regular websocket protocol over HTTPS. Clients can open a connection using any standard implementation at their disposal.

Websocket Packets #

All messages from the websocket transport are serialized using the WsPacket structure. They implement a set of protocol-level connectivity and authentication messages, plus a container type for client messages.

The WsPacket structure should not be confused with the message [Packet][Packet]. It’s an additional wrapping layer specific to the websocket transport. Actual comms messages are contained in the WsPeerUpdate type.

Field Type Value
message enum One of WsIdentification, WsChallengeRequired, WsSignedChallenge,
WsWelcome, WsPeerJoin, WsPeerLeave, WsKicked or WsPeerUpdate.

Authentication #

Before they can start relaying messages to others, clients must authenticate by signing a challenge string. This is required even when the transport URI was obtained from Archipelago after a previous round of authentication.

The first message a client sends when joining an island is WsIdentification , which contains a public address. It will be responded with WsChallengeRequired , and clients send a WsSignedChallenge in reply.

S e r v e W W r s s C W h e a l l c l o e W m W n s e s g S I e i d R g e e n n q e t u d i i C f r h C i e a o c d l n a l n t e e i n c o g C t n e l i e n t

If the flow is completed successfully, the client will receive a WsWelcome and can start sending messages to peers.


WsIdentification ↗ source #
Field Type Value
address string The public Ethereum address of the client

WsChallengeRequired ↗ source #
Field Type Value
challenge_to_sign string The server-provided string to be signed as proof of identity
already_connected string A server hint to clients, indicating that prior connections may be closed.

WsSignedChallenge ↗ source #
Field Type Value
auth_chain_json string A serialized authentication chain ending with the challenge signature.

WsWelcome ↗ source #
Field Type Value
alias uint32 A server-generated ID for the client’s session
peer_identities map<uint32, string> The addresses of all current peers, indexed by alias

Connectivity #

Three messages are defined to help clients keep track of their peers and their own status.

WsPeerJoin is received when a fellow client connects to the room and successfully authenticates, while WsPeerLeave is received when peers disconnect.

There’s also the WsKicked message, which informs clients that their connection is about to be closed and the reason for it. In current practice, the main reason a server can kick a client from a room is because they’ve simultaneously connected to another room, when that is forbidden by server policy.


WsPeerJoin ↗ source #
Field Type Value
alias uint32 The server-generated ID sent in WsWelcome
address string The new peer’s Ethereum address

WsPeerLeave ↗ source #
Field Type Value
alias uint32 The server-generated ID of the disconnected peer

WsKicked ↗ source #
Field Type Value
reason string The server’s explanation of why the connection will be closed

Client Messages #

To send comms messages , clients wrap them in the WsPeerUpdate structure. This differentiates the transport control message types from the actual messages sent between peers.

W s P a W c s k P e e P t e a r c U k p e d t a t e

WsPeerUpdate ↗ source #
Field Type Value
from_alias uint32 The sender’s server-generated ID
body bytes The serialized message being wrapped
unreliable bool Whether the sender prioritized speed or reliability for deliverying this message

Clients must set the from_alias field to 0 when sending, and the server will fill it with the correct identifier before delivering it to peers.