Routing Layer

The protocol specification is only relevant as background information or if you want to make your own Nabto WebRTC Signaling protocol implementation, e.g. for a currently unsupported target platform or app framework. For most applications, the standard implementations provided by Nabto through the available SDKs are sufficient - see the Applications guide.

The Nabto WebRTC Signaling protocol is split into four layers, this document is about the Routing layer:

  • WebRTC Signaling layer
  • Signing layer
  • Reliability layer
  • Routing layer

The Routing layer defines these Websocket messages:

  • PING
  • PONG
  • PEER_CONNECTED
  • PEER_OFFLINE
  • MESSAGE
  • ERROR

PING/PONG

If the PING message is sent on the Websocket, the Signaling service will respond with the PONG message. The PING message will NOT be relayed to the other peer. This message can be used to test if the Websocket connection is still open. This can be useful to shorten the connection timeout and reconnect faster if an event occurred in the system indicating the connection may have been lost (eg. the peer switched to another network).

{
    type: "PING" | "PONG",
}

PEER_CONNECTED

This message is sent by the Signaling service to peers. This is sent to client peers when their associated device connects to the Signaling service. Similarly, this is sent to the device when a client connects using its device ID.

{
  type: "PEER_CONNECTED",
  channelId: string,
}

The channel ID is the ID returned to the client in the /client/connect HTTP response.

PEER_OFFLINE

This message is sent by the Signaling service to peers. The service sends this in response to the peer sending a MESSAGEor ERROR message which could not be relayed to the other peer due to it not being connected to the service.

{
  type: "PEER_OFFLINE",
  channelId: string,
}

The channel ID is the ID returned to the client in the /client/connect HTTP response.

MESSAGE

This is relayed between peers by the Signaling service and is the message used for actual signaling messages.

{
  type: "MESSAGE",
  channelId: string,
  message: json,
  authorized?: boolean,
}

The channel ID is the ID returned to the client in the /client/connect HTTP response.

The message is the signaling message encoded in a string.

The optional authorized boolean should never be included when a peer sends this message to the Signaling service. It is, however, always added by the Signaling service before forwarding to the other peer. The boolean will be true if the client HTTP connect request was authorized and false otherwise. This boolean always represents the authorization status of the client and never the device, but is added in both directions by the Signaling service.

ERROR

This is relayed between peers by the Signaling service. This is used to indicate an error occurred in the other peer. This always represents an error fatal to the signaling channel between the peers and the peer should clean up any resources allocated to the particular channel ID.

SDK defined error codes are listed in the next section.

{
  type: "ERROR",
  channelId: string,
  error: {
    code: string,
    message?: string
  }
}

List of defined error codes

All error codes not starting with APPLICATION_* are defined in this section. A Nabto WebRTC Signaling Client or Device should be ready to accept new unknown error codes if they are added. In case they break application logic, the error codes should be defined and rolled out before they are actually used.

The purpose of the error codes is to give the application a possibility to handle the error programmatically. Since most of the errors are not supposed to happen in a production system, it will be a good idea to implement handlers for a specific few of them and log the rest to a centralized logging and error tracking system.

export enum SignalingErrorCodes {
  /**
   * The SDK received a message with invalid JSON or a JSON object not following the protocol
   */
  DECODE_ERROR = "DECODE_ERROR",
  /**
   * A signed message was received, but the signature could not be verified.
   */
  VERIFICATION_ERROR = "VERIFICATION_ERROR",
  /**
   * This error is received from the other peer when it is closing the Signaling Channel.
   */
  CHANNEL_CLOSED = "CHANNEL_CLOSED",
  /**
   * This error is sent to the SignalingClient by the SignalingDevice if the client is using an unknown Channel ID.
   */
  CHANNEL_NOT_FOUND = "CHANNEL_NOT_FOUND",
  /**
   * This can be sent by the device if a client attempts to create a new channel but the device has reached its limit.
   */
  NO_MORE_CHANNELS = "NO_MORE_CHANNELS",
  /**
   * This error code is sent if a channel is rejected based on authentication and/or authorization data.
   */
  ACCESS_DENIED = "ACCESS_DENIED",
  /**
   * This error is sent if the device or the client encounters an internal error.
   */
  INTERNAL_ERROR = "INTERNAL_ERROR"
}