I do also now prefer to use other languages than C++ to build servers, let it be Go, Java or C#. In all of those getting native webrtc data channel support is a giant effort, because there's neither sctp nor dtls support available. You could fallback on C libraries for this functionality, but that complicates the build process. Establishing HTTP, websocket or even HTTP/2 support is all easier than webrtc.
https://github.com/cjb/serverless-webrtc/
EDIT:
Aha! I based my code on: https://github.com/js-platform/node-webrtc/blob/develop/exam...
Replacing DTLS+SCTP with QUIC would be a good reduction in complexity, and we (the WebRTC team) are experimenting with doing so (https://cs.chromium.org/chromium/src/third_party/webrtc/p2p/...). It has a long way to go, but hopefully someday just having QUIC on your server will be enough.
(I work on WebRTC)
> I don't remember this being complex (there was some off-the-shelf library for getting a data connection on the server-side), but YMMV.
I've implemented all of these protocols before for use in VOIP. It's only necessary to discover an open port. Once you have that, it's clear sailing -- you never need to do it again. So I have no idea what the author means. If you have a connection on the open internet, then all of these protocols will realise that they need to do nothing.
Having said that, I have never used WebRTC, so possibly the author is confusing some other WebRTC issue with this.
It's not complex because it's already built-in to the browser, but if your network architecture is client-server (not p2p), you have to implement that entire stack even though none of it is strictly necessary when communicating to a public IP.
https://news.ycombinator.com/item?id=13264952
with the top comment claiming all of this was required:
https://chromium.googlesource.com/external/webrtc
and other options that may be newer:
Its still new, but we're starting to pick up some steam in the pace of development, and we have a pretty easy demo in the repo.
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.
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.
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'.
Here's a link to the library I've been working on: https://github.com/chadnickbok/librtcdcpp
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).
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.)
(ICE means trying STUN and falling back on TURN).
The ICE RFC does a good job of explaining it: https://tools.ietf.org/html/rfc5245#section-2.7
In addition, the SDP exchange also sets up DTLS, making sure that whoever the WebRTC SDP was exchanged with is the same as whoever connects at a low-level. While you can implement this as a messaging exchange over UDP once the connection is established, its a nice property that WebRTC doesn't even allow the connection to be established with a non-secured link.
I think the hardest part of the stack is getting a decent, stand-alone implementation. With things like Websockets creating a server is straightforward, but libraries for low-level webrtc are much harder to build.
Use the simple-peer library to hide away all that complexity. Just deactivate "trickle" for negotiation, then you get a simple Answer-Offer exchange with just one message each. I am using this to have WebRTC as a client-server proxy for UDP for my MMO game written in Golang.
Edit: Oh he mentions this, but invalidates it due to the complexity of typical P2P:
> But from a game developer point of view, all this complexity seems like dead weight, when STUN, ICE and TURN are completely completely unnecessary to communicate with dedicated servers, which have public IPs.
I don't remember this being complex (there was some off-the-shelf library for getting a data connection on the server-side), but YMMV.