or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mddata-channels.mdindex.mdmedia-streaming.mdnetwork-transport.mdpeer-connection.mdrtp-transport.mdstatistics.md

data-channels.mddocs/

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

```