Skip to content

Commit ff1a1ff

Browse files
committed
fix: capture early datachannels
1 parent 6a1f5f8 commit ff1a1ff

File tree

1 file changed

+42
-19
lines changed

1 file changed

+42
-19
lines changed

packages/transport-webrtc/src/muxer.ts

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,26 +40,39 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
4040
private readonly peerConnection: RTCPeerConnection
4141
private readonly metrics?: CounterGroup
4242
private readonly dataChannelOptions?: DataChannelOptions
43+
private readonly earlyDataChannels: RTCDataChannel[]
4344

4445
constructor (init: DataChannelMuxerFactoryInit) {
46+
this.onEarlyDataChannel = this.onEarlyDataChannel.bind(this)
47+
4548
this.peerConnection = init.peerConnection
4649
this.metrics = init.metrics
4750
this.protocol = init.protocol ?? MUXER_PROTOCOL
4851
this.dataChannelOptions = init.dataChannelOptions ?? {}
52+
this.peerConnection.addEventListener('datachannel', this.onEarlyDataChannel)
53+
this.earlyDataChannels = []
54+
}
55+
56+
private onEarlyDataChannel (evt: RTCDataChannelEvent): void {
57+
this.earlyDataChannels.push(evt.channel)
4958
}
5059

5160
createStreamMuxer (maConn: MultiaddrConnection): StreamMuxer {
61+
this.peerConnection.removeEventListener('datachannel', this.onEarlyDataChannel)
62+
5263
return new DataChannelMuxer(maConn, {
5364
peerConnection: this.peerConnection,
5465
dataChannelOptions: this.dataChannelOptions,
5566
metrics: this.metrics,
56-
protocol: this.protocol
67+
protocol: this.protocol,
68+
earlyDataChannels: this.earlyDataChannels
5769
})
5870
}
5971
}
6072

6173
export interface DataChannelMuxerInit extends DataChannelMuxerFactoryInit {
6274
protocol: string
75+
earlyDataChannels: RTCDataChannel[]
6376
}
6477

6578
export interface DataChannelMuxerComponents {
@@ -90,27 +103,37 @@ export class DataChannelMuxer extends AbstractStreamMuxer<WebRTCStream> implemen
90103
* {@link https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/datachannel_event}
91104
*/
92105
this.peerConnection.ondatachannel = ({ channel }) => {
93-
this.log('incoming datachannel with channel id %d, protocol %s and status %s', channel.id, channel.protocol, channel.readyState)
94-
95-
// 'init' channel is only used during connection establishment, it is
96-
// closed by the initiator
97-
if (channel.label === 'init') {
98-
this.log.trace('closing init channel %d', channel.id)
99-
channel.close()
100-
101-
return
102-
}
103-
104-
const stream = createStream({
105-
...this.streamOptions,
106-
...this.dataChannelOptions,
107-
channel,
108-
direction: 'inbound',
109-
log: this.log
106+
this.onDataChannel(channel)
107+
}
108+
109+
queueMicrotask(() => {
110+
init.earlyDataChannels.forEach(channel => {
111+
this.onDataChannel(channel)
110112
})
113+
})
114+
}
115+
116+
private onDataChannel (channel: RTCDataChannel): void {
117+
this.log('incoming datachannel with channel id %d, protocol %s and status %s', channel.id, channel.protocol, channel.readyState)
111118

112-
this.onRemoteStream(stream)
119+
// 'init' channel is only used during connection establishment, it is
120+
// closed by the initiator
121+
if (channel.label === 'init') {
122+
this.log.trace('closing init channel %d', channel.id)
123+
channel.close()
124+
125+
return
113126
}
127+
128+
const stream = createStream({
129+
...this.streamOptions,
130+
...this.dataChannelOptions,
131+
channel,
132+
direction: 'inbound',
133+
log: this.log
134+
})
135+
136+
this.onRemoteStream(stream)
114137
}
115138

116139
async onCreateStream (options?: CreateStreamOptions): Promise<WebRTCStream> {

0 commit comments

Comments
 (0)