Friday 6 February 2015

WebSockets over Node.js: from Plain to Secure

On a previous post I shared my experiments with node.js as a WebSocket server. This is quite useful for people working on WebRTC prototypes and familiar with node.js.

Some of the readers may have noticed that I was using plain WebSockets ('ws://' URLs). It's recommended to use Secure WebSockets instead ('wss://' URLs), so I thought of playing with the 'ws' node.js module and "add TLS".

On github there's an example in this direction (see below), but I must admit I didn't understand some implications at first.

I thought the instantiation of an HTTPS server was just coincidental and meant to provide the web pages and scripts in the example, and that the configuration of 'ws' with 'ssl: true' and certificates was independent.

It turns out it's not. The best description of my understanding is that you need an HTTPS server to "decorate" the WebSocket module. The HTTPS server will take care of connection instantiation and encryption, while the WebSocket module, "listening" on the same port, will take over when the Upgrade request [1] from the client is received.

Here's a snippet of the solution I've adopted, based on the example above:

You can see that the version for plain WebSocket (commented out) had the configuration object passed to the WebSocket constructor (well, in fact, you just need to pass '{ port: 8080 }'), while the secure solution passes the entire HTTPS server object to the WebSocket constructor.

Something similar (using express) has been described in this post.

Note, if you're using self-signed certificates, that you should first access the site and accept the security exception, or the client won't be happy.

An useful tool to debug WebSockets comes as Chrome extension: Simple WebSocket Client.

[1] The Upgrade request looks like this (from RFC 6455);

GET /chat HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Wednesday 4 February 2015

FOSDEM 2015 - part II

In "FOSDEM 2015 - part I" I made an overview of this Conference and a few comments on the talk "Python, WebRTC and you", where the a peer-to-peer WebRTC service was also described.

Fast forward to a Lightning talks on Day 1, afternoon: Emil Ivov about Jitsi VideoBridge.

In this case we’re considering video-conference scenarios, possibly with many participants, and the ability to add some presentation features, like highlighting the current speaker.

The architecture behind Jitsi VideoBridge aims to avoid a centralized mixer (MCU), but at the same time prevent the complexities of a Full Mesh approach.

Enter the SFU (Selective Forwarding Unit) concept: the server component is “simply” a router of media streams among conference participants. A IETF Draft describes the behaviour expected for an SFU. Each participant receives one stream per each other user: it’s then up to the receiving client to take care of stream presentation.

The SFU doesn't need to decode, mix, and then re-encode all the streams, and for this reason it can use just a small amount of resources, and scales well.

The critical point, as Emil is aware too, is dealing with mobile devices: low available bandwidth and relatively limited computational resources make it prohibitive for applications running on such devices to handle many different streams, some of each potentially carrying high-quality video.

What can help in this case is the concept of “simulcast”: compatible applications (like Chrome) are able to generate streams at different quality levels (resolution and framerate) at the same time. There are still some difficulties in using simulcast, as witnessed in this post. Different topologies involved in WebRTC networks are also well described in this other article.

Anyway the receiver of such streams can then instruct the server about which quality it is capable of receiving. Apps on mobile devices will get the low-quality streams; browsers on desktops will require the high-quality ones.

This is a clever solution, but I’d still like to experiment and see examples of mobile apps managing in an acceptable way more than 2-3 incoming streams, regardless of the optimized bandwidth usage. And if you have any reference, please feel free to post a comment!

Tuesday 3 February 2015

FOSDEM 2015 - part I

It's that time of the year when experts of Open Source software meet in frosty Brussels for two intense days of talks, conversations, and a good quantity of beer: FOSDEM.

Being just 2 hours away from London with the Eurostar, the relevance/effort ratio is very high. Additionally, the event is free and held over the weekend, so it has a low impact on the normal job activity (although on the other hand it does have some on your family time, but you can't have everything, unless your kids are big enough to join you, which I'd recommend).

Right after settling down in a lovely flat (AirBnB is a great choice) with three friends I started planning the sessions to follow. There are about twenty parallel sessions, so you must cherry pick. For day 1 I was oriented towards Configuration Management and Lightning Talks tracks. Day 2 had Virtualisation and Testing And Automation in my radar.

As it turns out, FOSDEM is such a success that the rooms are filled incredibly fast and many have even long queues outside. It was definitely the case for the Configuration Management dev room, which I had to skip in favour of Infrastructure As A Service.

So I got a basic understanding of Apache Mesos, for resource management of distributed systems, and GlusterFS, a distributed file system and general-purpose storage platform.
Apache Mesos will come back to attention on Day 2, when I'll learn more about CoreOS Rocket for container orchestration (more on this on a following post).

This year there wasn't any track dedicated to RTC (Real Time Communication), but nevertheless the topic was around a lot (not to mention the Internet Of Things track, which I gather has been very successful).

The Python devroom though offered an interesting cross between Python and WebRTC, with Saúl's "Python, WebRTC and you" (slides here). As the reader may know already, WebRTC doesn't mandate a signalling protocol, so this talk has been a good opportunity to show how conceptually easy is to interact with WebRTC's APIs (using rtcninja as wrapper), while at the same time managing signalling between browsers with a combination of Python3 and asyncio.

This talk alone, from a teaching perspective, is very valuable. You can see:
- The power of WebRTC: as long as the browser is compatible, you're just a few dozens of lines of code away from a new application.
- You can use the web server you prefer: web content servicing and signalling are just tools around the RTC.
- Unless you need some complex feature, you can leverage pure P2P and remove the server infrastructure from the equation.
- WebSocket support is increasing [1], making the life of WebRTC architects easier.

Of course things get more complicated for multiparty conferences, but there's something about this on a following post.

[1] The popular node.js platform has an ad-hoc module for WebSocket support too. I wrote about it and its usage inside a docker container in a previous post.

About ICE negotiation

Disclaimer: I wrote this article on March 2022 while working with Subspace, and the original link is here: