Skip to content

Commit 842a7e2

Browse files
authored
Merge pull request #237046 from enricohuang/patch-6
Add DataChannel feature doc
2 parents cf7b7b0 + 6e7374a commit 842a7e2

File tree

4 files changed

+285
-0
lines changed

4 files changed

+285
-0
lines changed
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
---
2+
title: Azure Communication Services Data Channel
3+
titleSuffix: An Azure Communication Services concept document
4+
description: Overview of Data Channel
5+
author: sloanster
6+
ms.author: micahvivion
7+
8+
services: azure-communication-services
9+
ms.date: 5/10/2023
10+
ms.topic: conceptual
11+
ms.service: azure-communication-services
12+
ms.subservice: calling
13+
---
14+
15+
# Data Channel
16+
17+
[!INCLUDE [Public Preview Disclaimer](../../includes/public-preview-include.md)]
18+
19+
> [!NOTE]
20+
> This document delves into the Data Channel feature present in the ACS Calling SDK.
21+
> While the Data Channel in this context bears some resemblance to the Data Channel in WebRTC, it's crucial to recognize subtle differences in their specifics.
22+
> Throughout this document, we use terms *Data Channel API* or *API* to denote the Data Channel API within the SDK.
23+
> When referring to the Data Channel API in WebRTC, we explicitly use the term *WebRTC Data Channel API* for clarity and precision.
24+
25+
The Data Channel API enables real-time messaging during audio and video calls. With this API, you can now easily integrate chat and data exchange functionalities into the applications, providing a seamless communication experience for users. Key features include:
26+
27+
* Real-time Messaging: The Data Channel API enables users to instantly send and receive messages during an ongoing audio or video call, promoting smooth and efficient communication. In group call scenarios, messages can be sent to a single participant, a specific set of participants, or all participants within the call. This flexibility enhances communication and collaboration among users during group interactions.
28+
* Unidirectional Communication: Unlike bidirectional communication, the Data Channel API is designed for unidirectional communication. It employs distinct objects for sending and receiving messages: the DataChannelSender object for sending and the DataChannelReceiver object for receiving. This separation simplifies message management in group calls, leading to a more streamlined user experience.
29+
* Binary Data Support: The API supports the sending and receiving of binary data, permitting the exchange of diverse data types, such as text, images, and files. The text messages must be serialized into a byte buffer before they can be transmitted.
30+
* Sender Options: The Data Channel API provides three configurable options when creating a sender object, including Reliability, Priority, and Bitrate. These options enable the configuration of a channel to meet specific needs for different use cases.
31+
* Security: All messages exchanged between a client and the other endpoint are encrypted, ensuring the privacy and security of users' data.
32+
33+
## Common use cases
34+
35+
These are two common use cases:
36+
37+
### Messaging between participants in a call
38+
39+
The Data Channel API enables the transmission of binary type messages among call participants.
40+
With appropriate serialization in the application, it can deliver various message types, extending beyond mere chat texts.
41+
Although other messaging libraries may offer similar functionality, the Data Channel API offers the advantage of low-latency communication.
42+
Moreover, by removing the need for maintaining a separate participant list, user management is simplified.
43+
44+
### File sharing
45+
46+
File sharing represents another common use cases for the Data Channel API.
47+
In a peer-to-peer call scenario, the Data Channel connection works on a peer-to-peer basis.
48+
This setup offers an efficient method for file transfer, taking full advantage of the direct, peer-to-peer connection to enhance speed and reduce latency.
49+
50+
In a group call scenario, files can still be shared among participants. However, there are better ways, such as Azure Storage or Azure Files.
51+
Additionally, broadcasting the file content to all participants in a call can be achieved by setting an empty participant list.
52+
However, it's important to keep in mind that, in addition to bandwidth limitations,
53+
there are further restrictions imposed during a group call when broadcasting messages, such as packet rate and back pressure from the receive bitrate.
54+
55+
## Key concepts
56+
57+
### Unidirectional communication
58+
The Data Channel API is designed for unidirectional communication, as opposed to bi-directional communication in WebRTC Data Channel. It employs separate objects for sending and receiving messages, with DataChannelSender object responsible for sending messages and the DataChannelReceiver object for receiving messages.
59+
60+
The decoupling of sender and receiver objects simplifies message handling in group call scenarios, providing a more streamlined and user-friendly experience.
61+
62+
### Channel
63+
Every Data Channel message is associated with a specific channel identified by `channelId`.
64+
It's important to clarify that this channelId isn't related to the `id` property in the WebRTC Data Channel.
65+
This channelId can be utilized to differentiate various application uses, such as using 100 for chat messages and 101 for image transfers.
66+
67+
The channelId is assigned during the creation of a DataChannelSender object,
68+
and can be either user-specified or determined by the SDK if left unspecified.
69+
70+
The valid range of a channelId lies between 1 and 65535. If a channelId 0 is provided,
71+
or if no channelId is provided, the SDK assigns an available channelId from within the valid range.
72+
73+
### Reliability
74+
Upon creation, a channel can be configured to be one of the two Reliability options: `lossy` or `durable`.
75+
76+
A `lossy` channel means the order of messages isn't guaranteed and a message can be silently dropped when sending fails. It generally affords a faster data transfer speed.
77+
78+
A `durable` channel means the SDK guarantees a lossless and ordered message delivery. In cases when a message can't be delivered, an exception will be thrown by the SDK.
79+
In the Web SDK, the durability of the channel is ensured through a reliable SCTP connection. However, it doesn't imply that message won't be lost in an end-to-end manner.
80+
In the context of a group call, it signifies the prevention of message loss between the sender and server.
81+
In a peer-to-peer call, it denotes reliable transmission between the sender and remote endpoint.
82+
83+
> [!Note]
84+
> In the current Web SDK implementation, data transmission is done through a reliable WebRTC Data Channel connection for both `lossy` and `durable` channels.
85+
86+
### Priority
87+
Upon creation, a channel can be configured to be one of the two Priority options: `normal` or `high`.
88+
89+
For the Web SDK, priority settings are only compared among channels on the sender side. Channels with a `high` priority are given higher precedence for transmission compared to the ones with `normal` priority.
90+
91+
### Bitrate
92+
When creating a channel, a desirable bitrate can be specified for bandwidth allocation.
93+
94+
This Bitrate property is to notify the SDK of the expected bandwidth requirement for a particular use case. Although the SDK generally can't match the exact bitrate, it tries to accommodate the request.
95+
96+
97+
### Session
98+
The Data Channel API introduces the concept of a session, which adheres to open-close semantics.
99+
In the SDK, the session is associated to the sender or the receiver object.
100+
101+
Upon creating a sender object with a new channelId, the sender object is in open state.
102+
If the `close()` API is invoked on the sender object, the session becomes closed and can no longer facilitate message sending.
103+
At the same time, the sender object notifies all participants in the call that the session is closed.
104+
105+
If a sender object is created with an already existing channelId, the existing sender object associated with the channelId will be closed and any messages sent from the newly created sender object will be recognized as part of a new session.
106+
107+
From the receiver's perspective, messages coming from different sessions on the sender's side are directed to distinct receiver objects.
108+
If the SDK identifies a new session associated with an existing channelId on the receiver's side, it creates a new receiver object.
109+
The SDK doesn't close the older receiver object; such closure takes place 1) when the receiver object receives a closure notification from the sender, or 2) if the session hasn't received any messages from the sender for over two minutes.
110+
111+
In instances where the session of a receiver object is closed and no new session for the same channelId exists on the receiver's side, the SDK creates a new receiver object upon receipt of a message from the same session at a later time. However, if a new session for the same channelId exists on the receiver's side, the SDK discards any incoming messages from the previous session.
112+
113+
Considering that the receiver object closes if it doesn't receive messages for more than two minutes, we suggest that the application periodically sends keep-alive messages from the sender's side to maintain the active status of the receiver object.
114+
115+
### Sequence number
116+
The sequence number is a 32-bit unsigned integer included in the Data Channel message to indicate the order of messages within a channel. It's important to note this number is generated from the sender's perspective. Consequently, a receiver may notice a gap in the sequence numbers if the sender alters the recipients during sending messages.
117+
118+
For instance, consider a scenario where a sender sends three messages. Initially, the recipients are Participant A and Participant B. After the first message, the sender changes the recipient to Participant B, and before the third message, the recipient is switched to participant A. In this case, Participant A will receive two messages with sequence numbers 1 and 3. However, this doesn't signify a message loss but only reflects the change in the recipients by the sender.
119+
120+
## Limitations
121+
122+
### Message size
123+
The maximum allowable size for a single message is 32 KB. If you need to send data larger than this limit, you'll need to divide the data into multiple messages.
124+
125+
### Participant list
126+
The maximum number of participants in a list is limited to 64. If you want to specify more participants, you'll need to manage participant list on your own. For example, if you want to send a message to 50 participants, you can create two different channels, each with 25 participants in their recipient lists.
127+
When calculating the limit, two endpoints with the same participant identifier will be counted as separate entities.
128+
As an alternative, you could opt for broadcasting messages. However, certain restrictions apply when broadcasting messages.
129+
130+
### Rate limiting
131+
There's a limit on the overall send bitrate, currently set at 500 Kbps.
132+
However, when broadcasting messages, the send bitrate limit is dynamic and depends on the receive bitrate.
133+
In the current implementation, the send bitrate limit is calculated as the maximum send bitrate (500 Kbps) minus 80% of the receive bitrate.
134+
135+
Furthermore, we also enforce a packet rate restriction when sending broadcast messages.
136+
The current limit is set at 80 packets per second, where every 1200 bytes in a message is counted as one packet.
137+
These measures are in place to prevent flooding when a significant number of participants in a group call are broadcasting messages.
138+
139+
## Next steps
140+
For more information, see the following articles:
141+
142+
- Learn about [QuickStart - Add messaging to your calling app](../../quickstarts/voice-video-calling/get-started-data-channel.md)
143+
- Learn more about [Calling SDK capabilities](../../quickstarts/voice-video-calling/getting-started-with-calling.md)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
ms.author: enricohuang
3+
title: Quickstart - Add Data Channel messaging to your calling app
4+
titleSuffix: An Azure Communication Services quickstart
5+
description: In this quickstart, you'll learn how to add Data Channel to your existing calling app using Azure Communication Services.
6+
author: sloanster
7+
services: azure-communication-services
8+
ms.date: 05/04/2023
9+
ms.topic: quickstart
10+
ms.service: azure-communication-services
11+
ms.subservice: calling
12+
ms.custom: mode-other
13+
---
14+
15+
# Quickstart: Add Data Channel messaging to your calling app
16+
17+
[!INCLUDE [Data Channel feature with JavaScript](./includes/data-channel/data-channel-javascript.md)]
18+
19+
## Next steps
20+
21+
For more information, see the following articles:
22+
23+
- Learn about [Data Channel feature concept document](../../concepts/voice-video-calling/data-channel.md)
24+
- Learn more about [Calling SDK capabilities](./getting-started-with-calling.md?pivots=platform-web)
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
ms.author: enricohuang
3+
title: Quickstart - Add messaging to your web calling app
4+
titleSuffix: An Azure Communication Services document
5+
description: In this quickstart, you'll learn how to add messaging to your existing web calling app using Azure Communication Services.
6+
author: sloanster
7+
services: azure-communication-services
8+
ms.date: 05/04/2023
9+
ms.topic: include
10+
ms.service: azure-communication-services
11+
ms.subservice: calling
12+
---
13+
14+
The Data Channel feature API enables real-time messaging during audio and video calls. In this quickstart guide, we'll illustrate how to integrate the Data Channel feature, enabling the exchange of text messages among participants within a group call.
15+
16+
17+
[!INCLUDE [Public Preview](../../../../includes/public-preview-include-document.md)]
18+
19+
>[!IMPORTANT]
20+
> Please be aware that our current implementation of the DataChannel feature API doesn't support direct messaging between a web browser and a native app in a peer-to-peer call scenario.
21+
22+
23+
## Create a DataChannelSender object
24+
First you need to create a DataChannelSender object to send messages. In this chat application, we suggest assigning a number to `channelId`, which serves to distinguish different application use cases. For instance, you can assign `channelId` 1000 for chat messages.
25+
26+
```js
27+
const dataChannel = call.feature(Features.DataChannel);
28+
const messageSender = dataChannel.createDataChannelSender({
29+
channelId: 1000
30+
});
31+
```
32+
33+
There are several other options, such as reliability, bandwidth, and priority. You can ignore these for now and use the default values.
34+
While the sender object is created, you still need a receiver object to receive messages.
35+
36+
## Register a listener to obtain the DataChannelReceiver object
37+
38+
To acquire a receiver object, you need to register a listener that captures the `dataChannelReceiverCreated` event.
39+
When a receiver object is created, the SDK emits the event along with the receiver object.
40+
41+
```js
42+
dataChannel.on('dataChannelReceiverCreated', receiver => {
43+
// receiver.channelId
44+
// reciever.senderParticipantIdentifier, which shows the sender id
45+
});
46+
```
47+
48+
Within the listener callback function, you can access the receiver object and retrieve information such as `channelId` and the sender participant ID `senderParticipantIdentifier`.
49+
It's your responsibility to maintain the receiver object reference, as the SDK emits the event once for each created receiver object.
50+
51+
## Handle messageReady and close event of DataChannelReceiver object
52+
53+
When a message arrives, the DataChannelReceiver object receives the message, stores it in its internal buffer, and emits a `messageReady` event.
54+
It's not necessary to register `messageReady` event listener to receive messages, as you can always call the `readMessage` API at any time.
55+
However, for best practice, we recommend reading message within the `messageReady` listener callback, if message processing takes a long time, you can
56+
offload the work to a Web Worker to prevent blocking the message reception.
57+
58+
```js
59+
dataChannel.on('dataChannelReceiverCreated', receiver => {
60+
if (receiver.channelId === 1000) {
61+
receiver.on('close', () => {
62+
console.log(`data channel id = ${receiver.channelId} from ${JSON.stringify(receiver.senderParticipantIdentifier)} is closed`);
63+
});
64+
receiver.on('messageReady', () => {
65+
const message = receiver.readMessage();
66+
// process the message
67+
});
68+
}
69+
});
70+
```
71+
## Set participants
72+
73+
To specify the recipients for your messages, you can use `DataChannelSender.setParticipants` API. The sender object maintains the most recent participant list you provide.
74+
The participant type is `CommunicationIdentifier`, which you can obtain from `remoteParticipant.identifier`. For more information, please refer to [Access remote participant properties](../../../../how-tos/calling-sdk/manage-calls.md?pivots=platform-web#access-remote-participant-properties).
75+
76+
```js
77+
const user = call.remoteParticipants[0]; // assume the user wants to send a message to the first participant in the remoteParticipants list
78+
messageSender.setParticipants([user.identifier]);
79+
```
80+
Please note that the participant list is limited to 64 participants. If the participant list is an empty array, the SDK broadcasts the message to all participants in the call.
81+
82+
## Send and receive messages
83+
84+
DataChannel feature API requires you to pass data as `Uint8Array` type. You can't directly send a JavaScript string using `sendMessage` API.
85+
For example, if you want to send a string `abc`, you can't use `sender.sendMessage('abc')`. Instead, you need to serialize the data to a byte buffer first.
86+
```js
87+
const data = (new TextEncoder()).encode('abc');
88+
sender.sendMessage(data);
89+
```
90+
Here's another example for sending a JSON object.
91+
```js
92+
const obj = {...}; // some object
93+
const data = (new TextEncoder()).encode(JSON.stringify(obj));
94+
sender.sendMessage(data);
95+
```
96+
97+
Receive and decode the message
98+
```js
99+
dataChannel.on('dataChannelReceiverCreated', receiver => {
100+
if (receiver.channelId === 1000) {
101+
const textDecoder = new TextDecoder();
102+
receiver.on('close', () => {
103+
console.log(`data channel id = ${receiver.channelId} from ${JSON.stringify(receiver.senderParticipantIdentifier)} is closed`);
104+
});
105+
receiver.on('messageReady', () => {
106+
const message = receiver.readMessage();
107+
const text = textDecoder.decode(message.data);
108+
console.log(`from ${JSON.stringify(receiver.senderParticipantIdentifier)}:${text}`);
109+
});
110+
}
111+
});
112+
```
113+
114+
You can find a complete sample at the following link: https://github.com/Azure-Samples/communication-services-web-calling-tutorial

articles/communication-services/toc.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ items:
106106
href: quickstarts/rooms/join-rooms-call.md
107107
- name: Use UI components for voice and video
108108
href: quickstarts/ui-library/get-started-composites.md
109+
- name: Add data channel messaging to your calling app
110+
href: quickstarts/voice-video-calling/get-started-data-channel.md
109111
- name: Chat
110112
items:
111113
- name: Connect to a chat
@@ -613,6 +615,8 @@ items:
613615
href: concepts/interop/enable-closed-captions.md
614616
- name: Media access
615617
href: concepts/voice-video-calling/media-access.md
618+
- name: Data channel
619+
href: concepts/voice-video-calling/data-channel.md
616620
- name: Video constraints
617621
href: concepts/voice-video-calling/video-constraints.md
618622
displayName: diagnostics, diagnose, feedback, quality, reliability, users, call, quick, satisfaction, improve, issues

0 commit comments

Comments
 (0)