0
# Data Communication
1
2
Send and receive text or binary data through WebRTC data channels with automatic buffering, backpressure handling, and full Node.js duplex stream compatibility.
3
4
## Capabilities
5
6
### Direct Data Sending
7
8
Send data directly through the WebRTC data channel once the connection is established.
9
10
```javascript { .api }
11
/**
12
* Send text/binary data to the remote peer via data channel
13
* @param chunk - Data to send (string, Buffer, ArrayBufferView, ArrayBuffer, or Blob)
14
* @throws {Error} ERR_DESTROYED - if peer is destroyed
15
* @throws {Error} If called before 'connect' event
16
*/
17
peer.send(chunk: string | Buffer | ArrayBufferView | ArrayBuffer | Blob): void;
18
```
19
20
**Usage Examples:**
21
22
```javascript
23
const peer = new Peer({ initiator: true });
24
25
peer.on('connect', () => {
26
// Send text data
27
peer.send('Hello, world!');
28
29
// Send binary data
30
const buffer = Buffer.from([1, 2, 3, 4, 5]);
31
peer.send(buffer);
32
33
// Send typed array
34
const uint8Array = new Uint8Array([6, 7, 8, 9, 10]);
35
peer.send(uint8Array);
36
37
// Send ArrayBuffer
38
const arrayBuffer = new ArrayBuffer(4);
39
const view = new DataView(arrayBuffer);
40
view.setUint32(0, 0x12345678);
41
peer.send(arrayBuffer);
42
});
43
44
// Don't call send() before connect
45
peer.send('This will throw an error!'); // ❌ Error
46
```
47
48
### Stream Interface
49
50
Use the Node.js duplex stream interface for buffered data communication with automatic backpressure handling.
51
52
```javascript { .api }
53
/**
54
* Write data to the peer connection (buffered if not connected yet)
55
* @param chunk - Data to write
56
* @param encoding - Character encoding (for strings)
57
* @param callback - Completion callback
58
* @returns false if buffer is full (backpressure)
59
*/
60
peer.write(chunk: any, encoding?: string, callback?: (err?: Error) => void): boolean;
61
62
/**
63
* Read data from the peer connection
64
* @param size - Number of bytes to read (optional)
65
* @returns Data read from stream or null if no data available
66
*/
67
peer.read(size?: number): any;
68
69
/**
70
* End the writable side of the stream
71
* @param chunk - Optional final chunk to write
72
* @param encoding - Character encoding
73
* @param callback - Completion callback
74
*/
75
peer.end(chunk?: any, encoding?: string, callback?: () => void): void;
76
```
77
78
**Usage Examples:**
79
80
```javascript
81
const Peer = require('simple-peer');
82
83
// Stream-style data sending
84
const peer1 = new Peer({ initiator: true });
85
const peer2 = new Peer();
86
87
// Setup signaling
88
peer1.on('signal', data => peer2.signal(data));
89
peer2.on('signal', data => peer1.signal(data));
90
91
// Write data (buffered until connected)
92
peer1.write('Message 1');
93
peer1.write('Message 2');
94
peer1.write(Buffer.from('Binary message'));
95
96
// Handle backpressure
97
const success = peer1.write('Large message');
98
if (!success) {
99
peer1.once('drain', () => {
100
console.log('Buffer drained, can write more');
101
});
102
}
103
104
// End the stream
105
peer1.end('Final message');
106
```
107
108
### Data Reception
109
110
Receive and handle incoming data from the remote peer.
111
112
```javascript { .api }
113
// Data event for incoming messages
114
peer.on('data', (data: Buffer | string) => void);
115
116
// Stream readable events
117
peer.on('readable', () => void);
118
peer.on('end', () => void);
119
120
// Stream writable events
121
peer.on('drain', () => void);
122
peer.on('finish', () => void);
123
```
124
125
**Usage Examples:**
126
127
```javascript
128
const peer = new Peer();
129
130
// Handle incoming data
131
peer.on('data', data => {
132
if (Buffer.isBuffer(data)) {
133
console.log('Received binary data:', data.length, 'bytes');
134
console.log('As string:', data.toString());
135
} else {
136
console.log('Received text:', data);
137
}
138
});
139
140
// Stream-style reading
141
peer.on('readable', () => {
142
let chunk;
143
while ((chunk = peer.read()) !== null) {
144
console.log('Read chunk:', chunk);
145
}
146
});
147
148
peer.on('end', () => {
149
console.log('Remote peer ended the stream');
150
});
151
152
// Handle buffer drainage
153
peer.on('drain', () => {
154
console.log('Write buffer drained - can write more data');
155
});
156
157
// Handle stream finish
158
peer.on('finish', () => {
159
console.log('Local peer finished writing data');
160
});
161
```
162
163
### Piping and Transform Streams
164
165
Use standard Node.js stream patterns for data processing.
166
167
```javascript { .api }
168
/**
169
* Pipe data to another stream
170
* @param destination - Destination stream
171
* @param options - Pipe options
172
* @returns Destination stream
173
*/
174
peer.pipe<T extends NodeJS.WritableStream>(destination: T, options?: { end?: boolean }): T;
175
```
176
177
**Usage Examples:**
178
179
```javascript
180
const fs = require('fs');
181
const { Transform } = require('stream');
182
183
const peer1 = new Peer({ initiator: true });
184
const peer2 = new Peer();
185
186
// Setup signaling
187
peer1.on('signal', data => peer2.signal(data));
188
peer2.on('signal', data => peer1.signal(data));
189
190
// Pipe to file
191
peer2.pipe(fs.createWriteStream('received-data.txt'));
192
193
// Pipe through transform stream
194
const upperCaseTransform = new Transform({
195
transform(chunk, encoding, callback) {
196
callback(null, chunk.toString().toUpperCase());
197
}
198
});
199
200
peer2.pipe(upperCaseTransform).pipe(process.stdout);
201
202
// Send data once connected
203
peer1.on('connect', () => {
204
peer1.write('hello world\n');
205
peer1.write('this is a test\n');
206
peer1.end();
207
});
208
```
209
210
### Buffer Management
211
212
Monitor and manage data channel buffering for optimal performance.
213
214
```javascript { .api }
215
/**
216
* Amount of data buffered in the data channel
217
*/
218
peer.bufferSize: number;
219
220
// Events for buffer management
221
peer.on('drain', () => void);
222
```
223
224
**Usage Examples:**
225
226
```javascript
227
const peer = new Peer({ initiator: true });
228
229
peer.on('connect', () => {
230
// Check buffer size before sending large data
231
if (peer.bufferSize < 32768) { // 32KB threshold
232
peer.send(largeBuffer);
233
} else {
234
console.log('Buffer full, waiting for drain');
235
peer.once('drain', () => {
236
peer.send(largeBuffer);
237
});
238
}
239
});
240
241
// Monitor buffer size
242
setInterval(() => {
243
console.log('Current buffer size:', peer.bufferSize, 'bytes');
244
}, 1000);
245
```
246
247
### Object Mode
248
249
Enable object mode for sending JavaScript objects directly.
250
251
```javascript { .api }
252
// Constructor option for object mode
253
const peer = new Peer({
254
initiator: true,
255
objectMode: true
256
});
257
```
258
259
**Usage Examples:**
260
261
```javascript
262
const peer1 = new Peer({ initiator: true, objectMode: true });
263
const peer2 = new Peer({ objectMode: true });
264
265
// Setup signaling
266
peer1.on('signal', data => peer2.signal(data));
267
peer2.on('signal', data => peer1.signal(data));
268
269
peer1.on('connect', () => {
270
// Send objects directly
271
peer1.write({ type: 'greeting', message: 'Hello!' });
272
peer1.write({ type: 'data', payload: [1, 2, 3, 4, 5] });
273
});
274
275
peer2.on('data', obj => {
276
console.log('Received object:', obj);
277
// { type: 'greeting', message: 'Hello!' }
278
// { type: 'data', payload: [1, 2, 3, 4, 5] }
279
});
280
```
281
282
### Error Handling
283
284
Handle data-related errors and edge cases.
285
286
```javascript { .api }
287
// Data channel specific error codes
288
interface DataChannelError extends Error {
289
code: 'ERR_DATA_CHANNEL' | 'ERR_DESTROYED';
290
}
291
```
292
293
**Usage Examples:**
294
295
```javascript
296
const peer = new Peer({ initiator: true });
297
298
peer.on('error', err => {
299
if (err.code === 'ERR_DATA_CHANNEL') {
300
console.error('Data channel error:', err.message);
301
} else if (err.code === 'ERR_DESTROYED') {
302
console.error('Cannot send data - peer destroyed');
303
}
304
});
305
306
// Handle write errors
307
peer.write('data', 'utf8', (err) => {
308
if (err) {
309
console.error('Write failed:', err.message);
310
} else {
311
console.log('Data sent successfully');
312
}
313
});
314
315
// Safe sending function
316
function safeSend(peer, data) {
317
if (peer.destroyed) {
318
console.error('Cannot send - peer destroyed');
319
return false;
320
}
321
322
if (!peer.connected) {
323
console.error('Cannot send - peer not connected');
324
return false;
325
}
326
327
try {
328
peer.send(data);
329
return true;
330
} catch (err) {
331
console.error('Send failed:', err.message);
332
return false;
333
}
334
}
335
```