Rework handshake to not generate offer SDP until other side asks
luser opened this issue · comments
Apparently SDPs have a short lifetime, part of which is because the client has to create NAT bindings and those bindings will expire. Because of this our current model of POSTing an offer SDP and waiting for a client to respond isn't a great approach. Instead we should probably do the following:
- Party A POSTs to /offer/create to get an ID
- Party A polls the /offer/ to wait for the other side
- Party B POSTs to /offer/ with an offer SDP
- Party B polls the /offer/ to wait for the answer SDP
- When Party A receives the offer SDP, they generate an answer SDP and POST it
- When Party B receives the answer SDP we're done (modulo trickle ICE, issue 6).
Here's what I'm thinking in terms of protocol redesign:
GET /channel
Creates a new channel. This request should be via EventSource, since it will be used to route all messages to the client. This EventSource will generate channel
events that originate from the broker and contain information like the assigned cid
and key
for a new channel. It will also generate message
events that originate from other channels on the broker.
The server should send:
event: channel
data: {cid: <guid>, key: <random-string>}
It will then send for any messages directed at this channel:
event: message
data: {sender: <cid>, message: <JSON>}
POST /session
Creates a new session using the arguments parsed from the request body.
{
cid: <cid>,
tags: <tags>,
list: <boolean>,
metadata: <JSON>
}
The server replies with the generated session id: {sid: <guid>}
. list
determines whether this session will be returned as part of a listing request. The server should verify that the host cid
exists. When the host channel is closed, any associated sessions should immediately become invalid.
POST /session/<sid>/update
Update session properties. Only valid properties can be updated, except for host
, which is only set on session creation and is thereafter read-only. The server replies with 200 OK
on success. The session key is the channel key of the session host.
{
cid: <cid>,
key: <key>,
values: {
tags: <tags>,
metadata: <JSON>
}
}
POST /send/<target>
Sends a message to the named target
, which may be a cid
or sid
.
{
origin: <guid>,
key: <key>,
message: <JSON>
}
POST /send/<target>
message format
For both send methods, the client receives a message with the following format:
{
origin: <guid>,
target: <guid>,
message: <JSON>
}
The target may be a cid
or sid
. Clients should always use the target
of a received message as the origin
of any reply messages.
GET /list?filter=<filter-string>
Get a list of sessions that pass the filter string. The filter string should include tags by listing them, and exclude tags by prepending !
to the tag name. For example, ?filter=tag1,!tag2
. Request can also be from EventSource. If so, updates to the list will be sent as events of the following form:
event: add
message: {sid: <sid>, session: <JSON>}
event: remove
message: {sid: <sid>}
Using the protocol above, handshake proceeds thusly:
-
Responder creates a
channelA
and asession
. -
Initiator create a
channelB
. -
Initiator sends SDP offer to
session
.{ offer: <SDP> }
-
Responder sends SDP answer to
channelB
.{ answer: <SDP> }
-
Responder updates
session
metadata, if necessary. -
Initiator closes
channelB
.
This has been fixed on the latest main branch.