0
# Data Channels
1
2
SCTP-based data channels for reliable application data transport with support for ordered/unordered delivery, partial reliability, and binary/text messages.
3
4
## Capabilities
5
6
### RTCDataChannel Class
7
8
Bidirectional data channel for sending application data between peers over SCTP transport.
9
10
```python { .api }
11
class RTCDataChannel:
12
"""Data channel for peer-to-peer application data transport."""
13
14
@property
15
def bufferedAmount(self) -> int:
16
"""Number of bytes queued for transmission"""
17
18
@property
19
def bufferedAmountLowThreshold(self) -> int:
20
"""Threshold for bufferedamountlow event (default: 0)"""
21
22
@bufferedAmountLowThreshold.setter
23
def bufferedAmountLowThreshold(self, value: int) -> None:
24
"""Set buffered amount low threshold"""
25
26
@property
27
def id(self) -> int:
28
"""Channel identifier (0-65534)"""
29
30
@property
31
def label(self) -> str:
32
"""Channel label/name"""
33
34
@property
35
def maxPacketLifeTime(self) -> int:
36
"""Maximum packet lifetime in milliseconds (None if not set)"""
37
38
@property
39
def maxRetransmits(self) -> int:
40
"""Maximum retransmission attempts (None if not set)"""
41
42
@property
43
def negotiated(self) -> bool:
44
"""Whether channel was pre-negotiated"""
45
46
@property
47
def ordered(self) -> bool:
48
"""Whether delivery is ordered"""
49
50
@property
51
def protocol(self) -> str:
52
"""Subprotocol name"""
53
54
@property
55
def readyState(self) -> str:
56
"""Channel state: "connecting", "open", "closing", "closed" """
57
58
def close(self) -> None:
59
"""Close the data channel"""
60
61
def send(self, data) -> None:
62
"""
63
Send data over the channel.
64
65
Parameters:
66
- data (str or bytes): Data to send
67
"""
68
```
69
70
### RTCDataChannelParameters Class
71
72
Configuration parameters for data channel creation.
73
74
```python { .api }
75
class RTCDataChannelParameters:
76
"""Data channel configuration parameters."""
77
78
def __init__(self, label: str, **options):
79
"""
80
Create data channel parameters.
81
82
Parameters:
83
- label (str): Channel label/name
84
- maxPacketLifeTime (int, optional): Maximum packet lifetime in milliseconds
85
- maxRetransmits (int, optional): Maximum retransmission attempts
86
- ordered (bool, optional): Whether to guarantee ordered delivery (default: True)
87
- protocol (str, optional): Subprotocol name (default: "")
88
- negotiated (bool, optional): Whether channel is pre-negotiated (default: False)
89
- id (int, optional): Numeric channel identifier (0-65534)
90
"""
91
92
@property
93
def label(self) -> str:
94
"""Channel label"""
95
96
@property
97
def maxPacketLifeTime(self) -> int:
98
"""Maximum packet lifetime in milliseconds"""
99
100
@property
101
def maxRetransmits(self) -> int:
102
"""Maximum retransmission attempts"""
103
104
@property
105
def ordered(self) -> bool:
106
"""Whether delivery is ordered"""
107
108
@property
109
def protocol(self) -> str:
110
"""Subprotocol name"""
111
112
@property
113
def negotiated(self) -> bool:
114
"""Whether pre-negotiated"""
115
116
@property
117
def id(self) -> int:
118
"""Channel identifier"""
119
```
120
121
### Data Channel Events
122
123
Data channels emit events for state changes and message reception.
124
125
```python { .api }
126
# Event types:
127
# "open" - Channel opened and ready for data
128
# "message" - Message received
129
# "error" - Error occurred
130
# "close" - Channel closed
131
# "bufferedamountlow" - Buffered amount below threshold
132
```
133
134
## Usage Examples
135
136
### Basic Data Channel Usage
137
138
```python
139
import aiortc
140
import asyncio
141
142
async def basic_data_channel():
143
pc1 = aiortc.RTCPeerConnection()
144
pc2 = aiortc.RTCPeerConnection()
145
146
# PC1 creates data channel
147
channel1 = pc1.createDataChannel("chat")
148
149
# Set up event handlers for PC1 channel
150
@channel1.on("open")
151
def on_open():
152
print("Channel opened on PC1")
153
channel1.send("Hello from PC1!")
154
155
@channel1.on("message")
156
def on_message(message):
157
print(f"PC1 received: {message}")
158
159
# PC2 handles incoming data channel
160
@pc2.on("datachannel")
161
def on_datachannel(channel):
162
print(f"PC2 received data channel: {channel.label}")
163
164
@channel.on("open")
165
def on_open():
166
print("Channel opened on PC2")
167
channel.send("Hello from PC2!")
168
169
@channel.on("message")
170
def on_message(message):
171
print(f"PC2 received: {message}")
172
173
# Perform signaling (simplified)
174
offer = await pc1.createOffer()
175
await pc1.setLocalDescription(offer)
176
await pc2.setRemoteDescription(offer)
177
178
answer = await pc2.createAnswer()
179
await pc2.setLocalDescription(answer)
180
await pc1.setRemoteDescription(answer)
181
182
# Wait for connection
183
print(f"Channel state: {channel1.readyState}")
184
```
185
186
### Data Channel with Custom Configuration
187
188
```python
189
async def custom_data_channel():
190
pc = aiortc.RTCPeerConnection()
191
192
# Create unreliable, unordered channel for game data
193
game_channel = pc.createDataChannel(
194
"game-state",
195
ordered=False, # Allow out-of-order delivery
196
maxPacketLifeTime=100, # Drop packets after 100ms
197
protocol="game-protocol" # Custom subprotocol
198
)
199
200
# Create reliable channel for chat
201
chat_channel = pc.createDataChannel(
202
"chat",
203
ordered=True, # Guarantee order
204
maxRetransmits=5 # Retry up to 5 times
205
)
206
207
print(f"Game channel: ordered={game_channel.ordered}, "
208
f"maxPacketLifeTime={game_channel.maxPacketLifeTime}")
209
print(f"Chat channel: ordered={chat_channel.ordered}, "
210
f"maxRetransmits={chat_channel.maxRetransmits}")
211
```
212
213
### Binary Data Transfer
214
215
```python
216
async def binary_data_transfer():
217
pc1 = aiortc.RTCPeerConnection()
218
pc2 = aiortc.RTCPeerConnection()
219
220
# Create data channel for file transfer
221
file_channel = pc1.createDataChannel("file-transfer")
222
223
@file_channel.on("open")
224
def on_open():
225
# Send binary data
226
with open("example.jpg", "rb") as f:
227
file_data = f.read()
228
229
print(f"Sending {len(file_data)} bytes")
230
file_channel.send(file_data)
231
232
# Handle incoming data channel on PC2
233
@pc2.on("datachannel")
234
def on_datachannel(channel):
235
received_data = b""
236
237
@channel.on("message")
238
def on_message(message):
239
nonlocal received_data
240
if isinstance(message, bytes):
241
received_data += message
242
print(f"Received {len(message)} bytes, "
243
f"total: {len(received_data)} bytes")
244
245
# Save received file
246
with open("received_file.jpg", "wb") as f:
247
f.write(received_data)
248
print("File saved!")
249
```
250
251
### Data Channel Flow Control
252
253
```python
254
async def flow_control_example():
255
pc = aiortc.RTCPeerConnection()
256
channel = pc.createDataChannel("bulk-data")
257
258
# Set low threshold for buffered amount
259
channel.bufferedAmountLowThreshold = 1024 # 1KB threshold
260
261
@channel.on("open")
262
def on_open():
263
# Send large amount of data
264
large_data = b"x" * 10000 # 10KB
265
266
if channel.bufferedAmount < channel.bufferedAmountLowThreshold:
267
channel.send(large_data)
268
print(f"Sent data, buffered: {channel.bufferedAmount} bytes")
269
270
@channel.on("bufferedamountlow")
271
def on_buffered_amount_low():
272
print("Buffer emptied, can send more data")
273
# Send more data when buffer is low
274
```
275
276
### Multiple Data Channels
277
278
```python
279
async def multiple_channels():
280
pc1 = aiortc.RTCPeerConnection()
281
pc2 = aiortc.RTCPeerConnection()
282
283
# Create multiple channels with different purposes
284
channels = {
285
"control": pc1.createDataChannel("control", ordered=True),
286
"video-metadata": pc1.createDataChannel("video-meta", ordered=False),
287
"bulk-data": pc1.createDataChannel("bulk", maxRetransmits=3)
288
}
289
290
# Set up handlers for each channel
291
for name, channel in channels.items():
292
@channel.on("open")
293
def on_open(channel_name=name):
294
print(f"Channel '{channel_name}' opened")
295
296
@channel.on("message")
297
def on_message(message, channel_name=name):
298
print(f"Channel '{channel_name}' received: {message}")
299
300
# Handle incoming channels on PC2
301
@pc2.on("datachannel")
302
def on_datachannel(channel):
303
print(f"PC2 received channel: {channel.label} (ID: {channel.id})")
304
305
@channel.on("message")
306
def on_message(message):
307
print(f"Channel {channel.label} got: {message}")
308
# Echo message back
309
channel.send(f"Echo: {message}")
310
```
311
312
### Error Handling
313
314
```python
315
async def error_handling():
316
pc = aiortc.RTCPeerConnection()
317
channel = pc.createDataChannel("test")
318
319
@channel.on("error")
320
def on_error(error):
321
print(f"Data channel error: {error}")
322
323
@channel.on("close")
324
def on_close():
325
print("Data channel closed")
326
327
@channel.on("open")
328
def on_open():
329
try:
330
# Try to send data
331
channel.send("Test message")
332
except Exception as e:
333
print(f"Send failed: {e}")
334
335
# Monitor channel state
336
print(f"Initial state: {channel.readyState}")
337
338
# Close channel when done
339
if channel.readyState == "open":
340
channel.close()
341
342
print(f"Final state: {channel.readyState}")
343
```