Connection Protocol - TUMFARSynchrony/SynthARium GitHub Wiki
Contents
Introduction
This page documents the protocol used for client-server connections. This includes sending and receiving messages, sending a stream to the server and receiving streams from the server.
In case you are unfamiliar with WebRTC, a good entry point to get a basic understanding can be:
- WebRTC.org: Getting started with WebRTC - a good overview over a typical WebRTC application flow
- WebRTC on mdn: WebRTC documentation on mdn
We're using (half-)trickle ICE to speed up the connection process. You can read up on it here:
Approach
To allow the experiment hub to modify the streams (audio and/or video tracks) of its users, all streams must be send to the Server.
For each incoming stream, the server applies relevant filters, records and then distributes the stream to other users.
This is mainly the task of the Connection
class, with help of SubConnection
s to distribute incoming streams to other users.
Establishing an Initial Connection
Description
In this step, the initial connection is established.
The initial connection provides the following features:
- Sending local tracks to the backend
- Receiving remote tracks based on the ones send
- Communications using a datachannel
Protocol
-
[Client] Initialize new RTCPeerConnection
- Create new RTCPeerConnection
- Add a data channel
- Add local (audio and video) tracks
- Add required event handlers to RTCPeerConnection here
- Generate uuid for connection
-
[Client] Create offer and send request to Server
- Create new WebRTC offer
- Set offer as local description
- Pack offer and additional parameters into request object:
sdp
: Session Description Protocol (SDP) of offer created in previous steptype
: type of the offer created in previous stepuser_type
: "participant" or "experimenter"connection_id
: uuid generated in step 1- If
user_type
isparticipant
participant_id
session_id
- Else
user_type
isexperimenter
:- TODO: Experimenter authentication
- Send request object to
<server address>/offer
- Body: stringified request object
- Method:
POST
- Mode: If Environment is DEVELOPMENT,
CORS
.
-
[Client] Send ICE candidates
- Everytime a new ice candidate is gathered:
- Pack candidate and id into request object:
id
: uuid created in step 1candidate
- Send request object to
<server address>/addIceCandidate
- Body: stringified request object
- Method:
POST
- Mode: If Environment is DEVELOPMENT,
CORS
.
- Pack candidate and id into request object:
- Everytime a new ice candidate is gathered:
-
[Server] Handle offer and respond with answer
- Ensure that contents of offer comply with the above definitions
- Additional checks, e.g. if
session_id
exists or ifparticipant_id
is part ofsession_id
. - Create new RTCPeerConnection
- Add event handlers to RTCPeerConnection here
- Set remote description of RTCPeerConnection to received offer
- Create WebRTC answer
- Set answer as local description
- Send response to client:
- On Error: Message containing Error
- On Success: Message with type
SESSION_DESCRIPTION
:sdp
: Session Description Protocol (SDP) of the answertype
: type of the answer- Optional:
participant_summary
: Participant Summary object
-
[Server] Handle ice candidates
-
[Client] Handle answer
- On Error: abort connection establishment -> connection failed
- On Success: Set remote description to answer in response
-
[Server] Handle incoming datachannel & tracks
- This step refers to event handlers that should be set in step 4, after the RTCPeerConnection is initialized in the Server
- Handle incoming datachannel
- Handle incoming tracks and send them back to the client
-
[Client] Handle incoming tracks
- This step refers to event handlers that should be set in step 1, after the RTCPeerConnection is initialized in the Client
- Tracks send to the backend should be send back now. Handlers for the
track
event set in step 1 will be called now
Note: Steps 2,4 and 3,5 happen at the same time and the order is not fixed.
Initial Connection Sequence Diagram Example
Adding a Sub Connection
Description
When the client needs to receive an additional stream, a sub connection is started.
A sub connection provides the following features:
- Receiving tracks from the backend
Sub connections should not include a datachannel, the initial connection is used for communication.
Protocol
-
[Server] Create new SubConnection and notify client
- Create RTCPeerConnection
- Add required event handlers to RTCPeerConnection
- Add video & audio tracks
- Create ConnectionProposal Message and send it to the client
- Endpoint / message type:
CONNECTION_PROPOSAL
- Endpoint / message type:
- Create RTCPeerConnection
-
[Client] Initialize WebRTC connection
- Create new RTCPeerConnection
- Add required event handlers to RTCPeerConnection here
- Create ConnectionOffer Message and send it to the server
- Endpoint / message type:
CONNECTION_OFFER
- Endpoint / message type:
-
[Client] Send ICE Candidates
- Everytime a new ice candidate is gathered:
- Create AddIceCandidate Message and send it to the server
- Endpoint / message type:
ADD_ICE_CANDIDATE
- Endpoint / message type:
- Create AddIceCandidate Message and send it to the server
- Everytime a new ice candidate is gathered:
-
[Server] Respond with
CONNECTION_ANSWER
- Handle offer in RTCPeerConnection created in step 1.
- Create answer
- Set local description to answer
- Create ConnectionAnswer Message and send it to the client
- Endpoint / message type:
CONNECTION_ANSWER
- Endpoint / message type:
-
[Server] Handle ICE candidates
-
[Client] Handle answer
- Set remote description to answer
Notes
- Step 1 / the
CONNECTION_PROPOSAL
ensures that the client always initiates the connection. This can help with ICE. - Steps 2,4 and 3,5 happen at the same time and the order is not fixed.