Both have serious shortcomings. `wrtc` uses the Google webrtc.org library which is overly complex since it includes lots of code for dealing with complex video/audio codec stuff that isn't needed to open a simple data channel. And if you're unlucky enough to be on a platform that they haven't made a prebuilt binary for, then you have to wait an hour for a bunch of Chrome-specific build tools to download and compile the library locally. Not fun to wait an hour after typing 'npm install'.
The other library, `electron-webrtc` literally launches a hidden instance of Electron and communicates with it over IPC from Node.js, which means it runs everywhere that Electron does (without waiting for anything to compile!), but it's a pretty heavy-handed approach. Launching a whole Chromium instance when you need a socket is, like, not ideal.
Another idea: how about implementing just the parts needed for Data Channel in JavaScript? A former Mozilla engineer, now Google engineer, actually tried this but gave up before finishing. His code is here: https://github.com/nickdesaulniers/node-rtc-peer-connection It's also not trivial since it requires a DTLS (TLS over UDP) implementation, and it's not exactly trivial to write one of those in JS. There is a chance that Node.js could expose the DTLS implementation from OpenSSL, since that's already part of Node. Then we could probably achieve a "pure JS" (no npm compile step) implementation of Data Channel. But there's still quite a bit more code needed to finish off this implementation. Discussion here: https://github.com/nodejs/node/issues/2398
I'm grateful to all the awesome folks that worked on these implementations, and this isn't meant to snub any of them. WebRTC is hard!
But this all goes to show just how overly complex WebRTC is, and why we really do need something like this post suggests, a low-level UDP API for the web.
I built a server-side WebRTC implementation for Twilio (as part of a team of two) in Java (with C bindings to libsrtp and openssl) in mid-2012 (and gradually evolved it over the next year and a half before moving on to a different team/project). I'm certainly not going to say it was easy, but it wasn't as hard as you're making it sound. It turns out you can cheat a lot here and there. You don't need TURN at all, and the ICE/STUN stuff can be dirt-simple because you don't need to deal with UDP hole punching or other esoteric things. You can cheat and hard-code most of the things that would usually need to be variable.
Honestly, most of the difficulty back in 2012 was because all of it was poorly documented and the standards were changing with every Chrome release, so it was partially a reverse-engineering effort. If I had to do it again from scratch (even though it's been at least 2 years since I've touched it), I could probably get something working in a week or two, and production-ready in a month or so.
I think a large part of the difficulty you describe is because you're trying to do this in Javascript. Doing it in a language that already has some library support for the various components cuts out a lot of the pain.
I had exactly the same experience (albeit more recently) getting a simple WebRTC DataChannels implementation up-and-running.
Once you realize its just ICE + DTLS + SCTP, and that each layer has a corresponding library, the work getting it up and running is mainly just 'plumbing'.
We are aware that it's a pain to use just the data channel, and we're working on it. We're refactoring the native API to be more ORTC-like and make it possible to compile without all the audio/video parts. It will take time, but it should become easier as we make progress.
I disagree that the solution is to expose UDP API to the web. Writing good congestion control is very hard, and it would not be safe to let web apps do that; doubly so for crypto. As for native apps (even JS/node ones): you already have a UDP API.
The solution is to make the WebRTC API easier to use and simplify the protocol stack. We're working on the first, as I mentioned. And we're experimenting with the second (by using QUIC instead of SCTP+DTLS). Again, it will take time, but eventually we'll get there (probably).
Feross, thanks very much for writing simple-peer! I used it to enable a server-cluster that acts as a WebRTC -> UDP proxy for my MMO game written in Golang. I am using electron-webrtc to run it under nodejs, which probably means about a gigabyte of overhead in total, but given the AWC EC2 pricing structure, I was doomed to be paying for more RAM that I plan on needing, so that turns out to be a non-issue for me.
As I was working on getting electron-webrtc running on my AWS Ubuntu instance, it occurred to me that it should be relatively easy (in other words, probably hours of tedious work) to abstract out the dependencies for everything that isn't required for only running WebRTC DataConnection. (I could produce a list of libraries to shim with placeholders. Call it 'drtc'?) If you are willing to give me some pointers, I'm willing to do the scut-work. (Contact info in my HN profile.)
The two best implementations on npm are `wrtc`: https://www.npmjs.com/package/wrtc and `electron-webrtc`: https://www.npmjs.com/package/electron-webrtc
Both have serious shortcomings. `wrtc` uses the Google webrtc.org library which is overly complex since it includes lots of code for dealing with complex video/audio codec stuff that isn't needed to open a simple data channel. And if you're unlucky enough to be on a platform that they haven't made a prebuilt binary for, then you have to wait an hour for a bunch of Chrome-specific build tools to download and compile the library locally. Not fun to wait an hour after typing 'npm install'.
The other library, `electron-webrtc` literally launches a hidden instance of Electron and communicates with it over IPC from Node.js, which means it runs everywhere that Electron does (without waiting for anything to compile!), but it's a pretty heavy-handed approach. Launching a whole Chromium instance when you need a socket is, like, not ideal.
Another idea: how about implementing just the parts needed for Data Channel in JavaScript? A former Mozilla engineer, now Google engineer, actually tried this but gave up before finishing. His code is here: https://github.com/nickdesaulniers/node-rtc-peer-connection It's also not trivial since it requires a DTLS (TLS over UDP) implementation, and it's not exactly trivial to write one of those in JS. There is a chance that Node.js could expose the DTLS implementation from OpenSSL, since that's already part of Node. Then we could probably achieve a "pure JS" (no npm compile step) implementation of Data Channel. But there's still quite a bit more code needed to finish off this implementation. Discussion here: https://github.com/nodejs/node/issues/2398
I'm grateful to all the awesome folks that worked on these implementations, and this isn't meant to snub any of them. WebRTC is hard!
We actually use `electron-webrtc` in `webtorrent-hybrid`, a CLI version of WebTorrent that can talk to "web peers" in browsers (https://github.com/feross/webtorrent-hybrid). Fortunately, most users can just install WebTorrent Desktop (https://webtorrent.io/desktop/) which works nicely.
But this all goes to show just how overly complex WebRTC is, and why we really do need something like this post suggests, a low-level UDP API for the web.