pi-webrtc

Messages

The messages on the socket, and the rules for devices and viewers. The messages are protobuf, defined in protos/cloudflare.proto of mazupo/protocol.

Frames

  • Each binary frame is one message.
  • A device sends DeviceRequest and gets DeviceResponse.
  • A viewer sends ViewerRequest and gets ViewerResponse.
  • Send the text frame ping every 15 seconds. The worker answers pong.

Device messages

FromMessageContents
Worker → devicejoineddevice_id, state, generation, rooms, ice_servers
Worker → devicewakeStart streaming: make a new PeerConnection and send an offer.
Device → workeroffersdp, tracks: [{ mid, track_name }], data_channels, voices
Worker → deviceanswergeneration, sdp
Device → workerreadyThe PeerConnection is connected.
Worker → devicechannelsThe ids of _lossy and _reliable
Worker → devicecontrolWho controls the device
Worker → deviceofferThe SFU's offer for the viewers' voices
Device → workeranswerThe answer to it
Worker → devicesleepStop streaming: close the PeerConnection.
Worker → deviceerrorSee Error codes.

Rules for devices:

  • Use only the reply to your last offer.
  • Send ready when the PeerConnection is connected. Viewers can pull your tracks only after that.
  • To keep the stream after a reconnect, send generation from your last answer in the token request.
  • After close code 4000 or 4002, try again later. Another device may use the same ID.

Viewer messages

FromMessageContents
Worker → viewerjoinedviewer_id, room, resumed, ice_servers, devices, subscriptions, data, viewers
Worker → viewerdeviceOne device's new state
Worker → viewermembersThe room's devices changed.
Worker → viewerviewersThe room's viewers changed.
Viewer → workerofferThe viewer's own offer
Worker → vieweranswerThe SFU's answer to it
Viewer → workersubscribetracks, data: [device_id], microphones: [viewer_id]
Worker → viewerofferThe SFU's offer: sdp, tracks, session_reset
Viewer → workeranswerThe answer to it
Worker → viewersubscribedtracks, data
Viewer → workerunsubscribemids, data
Viewer → workertake_control, release_control, control_readydevice_id
Viewer → workermutemuted
Viewer → workerleave
Worker → viewererrorSee Error codes.

Rules for viewers:

  • Right after joined, create a negotiated data channel server-events with id 0. Then send your own offer.
  • Answer each offer from the worker. After session_reset, start a new PeerConnection.
  • Subscribe only while the PeerConnection is connected.
  • If the PeerConnection fails, or your answer gets an error, start a new PeerConnection and send its offer. Then subscribe again. You keep your control.
  • If it is not connected 4 seconds after a device turns live, start over the same way.
  • Reconnect with the same viewer_id and secret within 30 seconds to keep your subscriptions.

Device states

StateMeaning
offlineNot connected.
sleepingConnected, not streaming.
wakingAsked to stream.
liveStreaming. Viewers can subscribe.

Close codes

CodeMeaning
4000A newer connection with the same ID and secret took over.
4001No ping for too long.
4002A live connection with another secret uses this ID.

Error codes

error has code, message, request (the failed request, such as offer), device_id, viewer_id, track_name and retryable.

CodeMeaning
INVALID_MESSAGEThe message cannot be read, or is not allowed now.
INTERNALSomething went wrong in the worker.
SFUA call to the SFU failed.
WAKE_STALEThe offer came after sleep.
WAKE_TIMEOUTThe device did not send ready in time.
ROOM_FULLThe room has MAX_DEVICES_PER_ROOM devices.
ROOM_UNAVAILABLEThe device could not join a room.
BUSYAnswer the last offer first.
NO_OFFERThere is no offer to answer.
NOT_MEMBERThe device is not in this room.
NOT_LIVEThe device is not streaming.
VIEWER_LIMITThe device has MAX_VIEWERS_PER_DEVICE viewers.
TRACK_NOT_FOUNDThe device has no track with this name.
TRACK_NOT_READYThe SFU could not pull the track yet. Try again.
VIEWER_GONEThe viewer is no longer in the room. Join again.
NO_DATA_CHANNELSThe device has no data channels.
DATA_CHANNELS_OFFThe token has no data_channels.
NOT_CONTROLLERYou do not control the device, and it is not being handed to you.
CONTROL_TIMEOUTNo control_ready within 5 seconds.
MICROPHONE_LIMITThe room has MAX_MICROPHONES_PER_ROOM microphones.

In the protobuf, each code has the prefix ERROR_CODE_.

Generated code

The worker's TypeScript for the messages is generated into src/proto. It is not in git. npm run dev, deploy and check generate it.

Edit on GitHub

On this page