News for hackers. Stuff that matters.
Re:A solution for enabling UDP in the web by just4suggest on Sunday February 26, 2017 @10:02PM (#13741520)
My memory is fuzzy, but I'm pretty sure I did this with WebRTC a while ago. Use RTCPeerConnection in unreliable mode, "peer" with the server, and you should have a UDP-backed SCTP connection. I'll try to dig up my PoCs on this.

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.

Re:A solution for enabling UDP in the web by TD-Linux on Sunday February 26, 2017 @11:38PM (#13741898)
That's because you don't need to implement any of those things for a basic client-server architecture. Unfortunately it looks like the author saw the massive and complex webrtc.org implementation and gave up, rather than try writing their own minimal implementation, or borrow from other implementations like Janus (https://janus.conf.meetecho.com/textroomtest.html).
Re:A solution for enabling UDP in the web by Matthias247 on Monday February 27, 2017 @04:28AM (#13742979)
There currently are only massive and complex implementations, because that's what the protocol requires. Even if you leave out the p2p bits you still need to get SCTP over UDP and DTLS support, which are both uncommon. The Janus thing also pulls in usrsctp and openssl for those. In Janus case there's even more things like libnice, which then requires you to use glib. All in all that's a massive set of C dependencies, which not everyone is comfortable pulling in. "Borrowing" from GPL software is also not what everybody is comfortable with. The webrtc.org reference implementation seems to contain half of chromes networking stack, which seems even worse.

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.

Re:A solution for enabling UDP in the web by just4suggest on Monday February 27, 2017 @12:02AM (#13742010)
Yes; vaguely... there was some (string) message format that you could manually stitch together with the right IP and port, etc, and basically tell the browser's WebRTC implementation "other client is on this IP and port". I seem to have deleted this code unfortunately, the only thing I saved is this link:

https://github.com/cjb/serverless-webrtc/

EDIT:

Aha! I based my code on: https://github.com/js-platform/node-webrtc/blob/develop/exam...

Re:A solution for enabling UDP in the web by TD-Linux on Monday February 27, 2017 @12:28AM (#13742099)
Yup, the format is called SDP. It's an old, crufty, and mostly effective way to specify not only the port and IP, but also whether a TCP fallback is being used, video and audio formats, and other things you can mostly ignore when just using data channels. See the "answer" section of 5.2.3 of [1], for details of some of the other magic numbers (which your JS library should handle for you). You can also check out about:webrtc to see SDPs made by other websites, like the Janus demo page.

[1] https://tools.ietf.org/html/draft-ietf-rtcweb-sdp-03

Re:A solution for enabling UDP in the web by pthatcherg on Monday February 27, 2017 @06:17PM (#13749484)
You need to implement DTLS and SCTP for client->server, just not ICE. But client->server ICE is fairly trivial with ICE lite. It's DTLS+SCTP that are complex, and they don't go away client->server.

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)

Re:A solution for enabling UDP in the web by mikekchar on Sunday February 26, 2017 @10:48PM (#13741728)
>> 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.

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.

Re:A solution for enabling UDP in the web by banachtarski on Sunday February 26, 2017 @11:33PM (#13741885)
No you're missing his point which is that implementing STUN, ICE, TURN server side is completely pointless.

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.

Re:A solution for enabling UDP in the web by j_s on Sunday February 26, 2017 @11:24PM (#13741857)
The linked HN discussion has a few options:

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:

https://github.com/chadnickbok/librtcdcpp

Re:A solution for enabling UDP in the web by chadnickbok on Monday February 27, 2017 @12:38PM (#13746044)
Hi! I'm one of the authors of librtcdcpp.

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.

Re:A solution for enabling UDP in the web by j_s on Monday February 27, 2017 @03:33PM (#13747680)
If you're actively pursuing "the simplest server-side WebRTC UDP implementation" and the associated tech support then you should throw UDP into your project description and README alongside "DataChannels" for noobs like me.
Re:A solution for enabling UDP in the web by benaadams on Sunday February 26, 2017 @10:05PM (#13741536)
The WebRTC Data channel is still unavailable in Opera, Edge and Safari... :( https://developer.microsoft.com/en-us/microsoft-edge/platfor...
Re:A solution for enabling UDP in the web by taf2 on Sunday February 26, 2017 @10:37PM (#13741675)
Opera works - Safari is working on it? At least in my case, we sell web based phone system and pretty much that means we don't target IE/Edge or Safari simply due to the lack of WebRTC.
Re:A solution for enabling UDP in the web by daveorzach on Monday February 27, 2017 @10:30AM (#13744898)
Looks like it is coming to Safari soon

https://bugs.webkit.org/show_bug.cgi?id=168858

Re:A solution for enabling UDP in the web by feross on Monday February 27, 2017 @12:17AM (#13742057)
I'm the author of WebTorrent, and let me tell you that getting WebRTC to run server-side is not fun.

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.

Re:A solution for enabling UDP in the web by kelnos on Monday February 27, 2017 @06:17AM (#13743409)
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.

Re:A solution for enabling UDP in the web by chadnickbok on Monday February 27, 2017 @12:40PM (#13746064)
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'.

Here's a link to the library I've been working on: https://github.com/chadnickbok/librtcdcpp

Re:A solution for enabling UDP in the web by pthatcherg on Monday February 27, 2017 @06:27PM (#13749580)
(Member of the Google WebRTC team here)

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).

Re:A solution for enabling UDP in the web by stcredzero on Monday February 27, 2017 @01:10PM (#13746347)
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.)

Re:A solution for enabling UDP in the web by fulafel on Monday February 27, 2017 @12:03AM (#13742015)
IIRC the NAT traversal workarounds are optional in WebRTC? Just don't supply STUN/TURN servers when setting up a connection. Then you don't need to worry about it on the server side either.

(ICE means trying STUN and falling back on TURN).

Re:A solution for enabling UDP in the web by chadnickbok on Monday February 27, 2017 @12:42PM (#13746081)
You must supply a STUN/Turn server to the browser when setting up the connection, but if you're connecting to a public server you can use ICE-Lite implementations server-side to simplify the setup.

The ICE RFC does a good job of explaining it: https://tools.ietf.org/html/rfc5245#section-2.7

Re:A solution for enabling UDP in the web by pthatcherg on Monday February 27, 2017 @06:29PM (#13749598)
You don't need to give a server. It works fine with just host ICE candidates from the server and no stun or relay candidates.
Re:A solution for enabling UDP in the web by chadnickbok on Monday February 27, 2017 @12:50PM (#13746178)
NAT traversal is part of ICE, but another part is formally specifying things like how to trigger accepting a connection, and which connection can be tied to which WebRTC session. This can actually make it easier, not harder, to use WebRTC.

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.

Re:A solution for enabling UDP in the web by stcredzero on Monday February 27, 2017 @12:58PM (#13746238)
Edit: Oh he mentions this, but invalidates it due to the complexity of typical P2P

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.