simple-peer icon indicating copy to clipboard operation
simple-peer copied to clipboard

Create multiple DataChannels

Open t-mullen opened this issue 4 years ago • 11 comments

Reimplementation of #334. Implements #19

It allows you to use the same Peer duplex stream as before by having the peers inherit the DataChannel object. But it also allows you to do multiplexing easily like this:

var dc = peer1.createDataChannel('secondChannel')
peer.on('datachannel', (dc) => {
  dc // Duplex stream!
  dc.channelName // "secondChannel"
  dc.on('open', () => {
    dc.write('test') // each DataChannel is a duplex
    dc.end() // you can close secondary DataChannels without destroying the main peer
  })
  dc.write('test') // writing before "open" will buffer data
})

peer.write('abc') // Peer is still a Duplex, data goes through a "default" Datachannel

Open Problems:

  • [ ] Firefox won't emit datachannel events created after a channel is closed. https://bugzilla.mozilla.org/show_bug.cgi?id=1513107
  • [ ] There is no guarantee that both sides of the DataChannel will be flushed before it is closed (potentially causing some messages to never arrive). This is not a new issue.

Additional Changes:

  • Fixes #721 by using the default DataChannel's state to determine connection.
  • Fixes documentation bug for #690

Tested on all combinations of these SauceLabs emulators: iOS 13.4 @ macOS 10.15 Android 10.0 @ Linux Microsoft Edge 84 @ macOS 10.15 Firefox 79 @ macOS 10.15 Google Chrome 84 @ macOS 10.15 Safari 13 @ macOS 10.15

As well as all combinations of these real browsers: Brave 1.10.97 @ macOS 10.15.5 Google Chrome 84.0.4147.105 @ macOS 10.15.5 Firefox 79.0 @ macOS 10.15.5 Safari 13.1.1 @ macOS 10.15.5

t-mullen avatar Jun 30 '20 13:06 t-mullen

To be completely honest, after working a with WebRTC for so long I no longer think more advanced features need to be added to simple-peer. It is pretty easy to implement multiplexing/demultiplexing yourself if you really need it or just create multiple data channels.

nazar-pc avatar Aug 08 '20 23:08 nazar-pc

It is pretty easy to implement multiplexing/demultiplexing yourself if you really need it or just create multiple data channels.

Is there any prior art/example for this? I've tried it and failed. One problem for doing it over a single data channel for me was that I have a lot of binary data I'm sending but also need the occasional short, "quick" message to be sent immediately. But I found that the large binary data was saturating the channel already and it took a long time for this quick message to go out. On the other hand, if multiple channels can be created with the current master, I'd love to know how people did that!

stephanos avatar Aug 09 '20 00:08 stephanos

It depends heavily on your needs. You can simply create multiple native data channels with different names (and use the first one created for renegotiations only). Or since data channels are message-based, you can start each message with one byte indicating which multiplex channel is used, that was you immediately can have up to 256 possible multiplexed channels. If you want to interleave messages from different channels depending on priority that is also relatively straightforward to do.

nazar-pc avatar Aug 09 '20 00:08 nazar-pc

It is pretty easy to implement multiplexing/demultiplexing yourself if you really need it

I originally felt the same way about multiplexing, but doing it in JS requires a significant amount of CPU resources even if done right. (Something I learned the hard way implementing simultaneous file transfer for FileFire). Multiple datachannels give you all that for free.

or just create multiple data channels.

This PR just allows you to create multiple DataChannels. Calling it "multiplexing" isn't exactly accurate as it doesn't turn the Peer into a Multiplex stream.

I no longer think more advanced features need to be added to simple-peer.

This is always something to consider. I'd hate for feature creep to make simple-peer unapproachable to a beginner. However, the core API is exactly the same and these DataChannels can be ignored completely (I expect most users to do just that). Anyone using simple-peer for an application that uses >1 stream of data or events will truly need this feature. Notable examples of this include chat clients and file transfer - the flagship usecases of WebRTC.

If complexity of API is your main concern, would you prefer if advanced features like multistreaming, multiple datachannels, etc were pulled out of the README into "advanced documentation"? I would agree with this.

The "simple" part of simple-peer, at least to me, implies the powerful features of WebRTC are simplified - not that "complex" features are cut entirely for the sake of simplicity. Renegotiation, trickle ice and multistreaming are all very complicated but simple-peer turns them into one-liner constructor arguments and method calls - which is what I love about this library.

t-mullen avatar Aug 09 '20 00:08 t-mullen

I was misled by previous title then, I though it is "multiplexing" not multiple data channels. Makes sense then, I'll try to find time to review.

nazar-pc avatar Aug 09 '20 00:08 nazar-pc

OK, my bad for calling it "multiplexing" - I think it was first called that in the initial feature request. It is not.

t-mullen avatar Aug 09 '20 00:08 t-mullen

hello! any update when this could be merged ? Thank you in advance :-)

pedubreuil avatar Nov 09 '20 14:11 pedubreuil

I'm also interested in this! I'm thinking in stream video over a data channel, but continue keeping a data channel with JSON messages

ricardopolo avatar Dec 04 '20 01:12 ricardopolo

@feross @nazar-pc any updates on this?

HR avatar Mar 02 '21 22:03 HR

showing interest here. commented on the #19

disarticulate avatar Mar 07 '21 15:03 disarticulate

Is this PR dead? Would be nice to have the ability to add additional data channels to a simple-peer WebRTC connection without having to resort to snooping the codebase and meddling with private fields etc.

toebeann avatar Jun 08 '22 16:06 toebeann