Proposed data channel API

https://docs.google.com/document/pub?id=16csYCaHxIYP83DzCZJL7relQm2QNxT-qkay4-jLxoKA
*
*

A proposal for  <http://dev.w3.org/2011/webrtc/editor/webrtc.html>
http://dev.w3.org/2011/webrtc/editor/webrtc.html, to discuss in tomorrow's
TPAC meeting.
5 The data stream

In addition to the MediaStreams defined earlier in this document, here we
introduce the concept of DataStreams for PeerConnection. DataStreams are
bidirectional p2p channels for real-time exchange of arbitrary application
data in the form of datagrams. DataStreams can either be reliable, like
TCP, or unreliable, like UDP, and have built-in congestion control, using a
TCP-fair congestion control algorithm.

DataStreams are created via the new PeerConnection.createDataStream method.
This method creates a new DataStream object, with specified "label" and
"reliable" attributes; these attributes can not be changed after creation.
DataStreams can then be added to a PeerConnection, much in the same way
that MediaStreams are added. Since the semantics of the existing addStream
API don't fit perfectly here (i.e. MediaStreamHints), we add the new
addDataStream and removeDataStream APIs for this purpose. As with
addStream/removeStream, these APIs update the internal session description
of the PeerConnection, and cause a new offer to be generated and signaled
through the PeerConnection signaling callback. Note that there is no
requirement to add a MediaStream first before adding a DataStream; rather,
it is expected that many uses of PeerConnection will be solely for
application data exchange.

Like MediaStreams, multiple DataStreams can be multiplexed over a single
PeerConnection. Each DataStream has a priority, which indicates what
preference should be given to each DataStream when a flow-control state is
entered. DataStreams with the highest priority are given the first
notification and ability to send when flow control lifts.

In reliable mode, in-order delivery of messaging is guaranteed, which
implies head-of-line blocking. In unreliable mode, messages may arrive out
of order. In either mode, notifications of message delivery are
communicated to the application via a callback; in unreliable mode,
failures (defined as an elapsing of 2 RTT without an acknowledgement) are
communicated through the same callback.

There is no maximum size to a datagram that can be sent over the data
stream. However, messages are not interleaved on the wire, so a very large
message will prevent other messages from being sent until its own send
completes.

Encryption of the data stream is required. It is expected that applications
that support DataStreams will support DTLS and DTLS-SRTP; while SDES-SRTP,
or plain old RTP may be supported for legacy compatibility, there is no
need to support DataStreams in these scenarios.

In this draft, there is no inheritance relationship between MediaStream and
DataStream, which is intentional due to the lack of a "is-a" relationship.
However, it may make sense to hoist a Stream ancestor class for both
MediaStream and DataStream, which would allow many of the existing
PeerConnection APIs (localstreams, remotestreams, onaddstream,
onremovestream, maybe removeStream) to refer to a Stream instead of the
MediaStream that they currently reference. This would eliminate the need
for "data" variants of all the aforementioned functions.
5.1 Changes to PeerConnection

interface PeerConnection {

   [...]

   // Creates a data stream, either reliable or unreliable.

   // Reliability cannot be changed for a stream after it is created.

   DataStream createDataStream(in DOMString label, in boolean reliable);

   // Adds a datastream to this PeerConnection. Will trigger new signaling.

   void add<http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-PeerConnection-addStream-void-MediaStream-stream-MediaStreamHints-hints>
DataStream<http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-PeerConnection-addStream-void-MediaStream-stream-MediaStreamHints-hints>
(in
DataStream<http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-MediaStream>
 stream);

   // Removes a datastream from this PeerConnection. Will trigger new
signaling.
   void removeDataStream<http://dev.w3.org/2011/webrtc/editor/webrtc.html#widl-PeerConnection-removeStream-void-MediaStream-stream>
(in
DataStream<http://dev.w3.org/2011/webrtc/editor/webrtc.html#idl-def-MediaStream>
 stream);

   [...]
};

5.2 The DataStream interface

 interface DataStream {

   // Label, like MediaStream's |label|.

   // Maps to a lower-level stream identifier.
   readonly attribute DOMString label;

   // Whether this stream has been configured as reliable.

   readonly attribute boolean reliable;

   // The relative priority of this stream.

   // If bandwidth is limited, higher priority streams get preference.

   // Default priority is zero.

   attribute long priority;

   // States, as in MediaStream.
   const unsigned short LIVE = 1;

   const unsigned short ENDED = 2;
   readonly attribute unsigned short readyState;
   attribute Function onReadyStateChange;

   // Sends the supplied datagram.

   // Returns a nonnegative message id if the send was successful.

   // Returns -1 if the stream is flow-controlled.

   long sendMessage(in DOMString message);

   // Called when a message is received.

   // Arguments: DOMString message

   attribute Function onMessage;

   // Called when flow control lifts for this stream.

   // Arguments: None

   attribute Function onReadyToSend;

   // Called when a message has been delivered (or lost, if unreliable).

   // Arguments: long id, bool success

   attribute Function onSendResult;
}

5.3 Example

// standard setup from existing example
var local = new PeerConnection('TURNS  <http://example.net/>example.net',
sendSignalingChannel);

// create and attach a data stream
var aLocalDataStream = local.createDataStream("myChannel", false);

local.addDataStream(aLocalDataStream);

// outgoing SDP is dispatched, including a media block like:

    m=application 49200 <TBD> 127

    a=rtpmap:127 application/html-peer-connection-data

 // this SDP is plugged into the remote onSignalingMessage, firing
onAddStream

[remote] onAddStream(aRemoteDataStream);

// signaling completes, and the data stream goes active on both sides

[local] onReadyToSend();

[remote] onReadyToSend();

    // we start sending data on the data stream

var id = aLocalDataStream.send("foo");

// the message is delivered

[remote] onMessage("foo");

// the result is communicated back to the sender

[local] onSendResult(id, true);

// the data stream is discarded

local.removeDataStream(aLocalDataStream)

// new signaling is generated, resulting in onRemoveStream for the remote

[remote] onRemoveStream(aRemoteDataStream);

5.4 Implementation notes

It is intended that this API map to the wire protocol and layering being
defined in the IETF RTCWEB WG for the data channel. One current proposal
for said protocol is

http://www.ietf.org/id/draft-jesup-rtcweb-data-00.txt, which is believed to
match the requirements of this API.

Received on Monday, 31 October 2011 04:51:50 UTC