WebRTC over QR
This is a project exploring how close we can get to a truly Peer-to-Peer WebRTC experience: just a single offline HTML file on the host, bootstrapped onto the guest via <2,953 bytes of HTML squeezed into a single QR code (plus a return QR code is required for some browser engines). No servers in the middle, just two web browsers speaking WebRTC and JavaScript to each other.
Please read the caveats below before trying it out! It is incredibly cool that it is even possible, and even somewhat portable between browsers (though Chromium works best), and I have done my best to smooth out the rough edges to make it pleasant to use. The concept underlying the connection procedure is relatively simple, and I have written a chat app on top to demonstrate its usefulness and test aspects like latency (try running /ping).
More information and downloads at https://webrtc-over-qr.veritates.love/.
Caveats
WebRTC discovery works differently across browser engines. Chromium-based browsers give the nicest experience: we are able to auto-discover guests when they open the page and try to connect. On other engines (like Safari and Firefox), the certificate fingerprint generated by the guest must be sent back to the host via some other method (QR code, copy+paste, instant message, verbal transcription, etc.).
Our mode of connection (entirely peer-to-peer) is somewhat unintended, as WebRTC was designed to have a (trusted!) signaling server mediate a connection. Thus there is no uniform experience we can offer, although we can try our best and add workarounds for these situations.
Firefox behaves very differently based on the flag
media.peerconnection.ice.obfuscate_host_addressesinabout:config(which is set totrueby default). In particular, it seems to impose a ~5 second timeout as guest. And as host, it will not connect to a Chromium guest? So you might want to set this tofalsewhile trying the demo, or use a different browser instead. Note that it is a global setting, so remember to set it back to the defaulttruewhen you are done.While we produce standards-compliant QR codes, they aren't exactly usable by existing software: the QR code generated by the host contains a data URI, which most phone apps will not recognize as a link, and even if they do, browsers will not open data URIs from external sources (or in the case of Firefox on iOS, ever at all), so you may have to use a different QR code scanner and copy and paste the URL into a browser. And on the flip side, the QR code generated by the guest is 32 bytes of raw binary data, which most scanners will not even display for you, and would not be safe to copy as text. However, this is less of an issue since we can embed a QR scanner here in secure contexts (HTTPS, localhost, and apparently local files too).
A lot of nice web APIs understandably do not work in insecure contexts. This experiment of bootstrapping a peer-to-peer web chat over QR is not secure and there is not much we can do about it. This means no access to webcams or microphones, no popup notifications, etc., at least from the guest. But there is still a lot of amazing things that we can do, things that any (web) chat app could have done but didn't.
The demo has no way of reestablishing a connection if it drops (I do not know if it would be technically possible at all without manually passing information between the peers again ... you could at least pre-establish the certificates to use). The demo also does not use STUN or TURN servers, which facilitate connections behind NAT/firewalls, so it may only work between devices on your local network.
Instructions
First, load the provided HTML on the guest device. You have a few options for doing this, but they all have some difficulties.
Load the data URI:
Use some (other) instant messaging to text the data URI to the guest device, and copy and paste it into the browser from there.
Use a compatible QR code scanner to scan the QR code and copy the data URI from it into the browser. Most QR scanners will not automatically scan it, since it is not an HTTP or HTTPS URL!
Load the HTML directly:
You can save the HTML as a
.htmlfile and open it in the browser (at least on desktop computers).Or, if you know what you're doing, you can temporarily host it on a local webserver, or some similar solution.
Don't bother with a separate guest device:
See the Side-by-side tab here:
Once the guest device loads it, if the connection does not automatically establish itself (if your host is not Chromium), you will need to get the certificate fingerprint from the guest. You can copy/paste it or enter it manually, or, if the host is loaded in a secure context, you can use the QR code scanner below by selecting a camera to use. Or you can take a picture of the QR code in another app and upload/paste it here.
The WebRTC connection is not particularly time sensitive, so you should have time to open the site on the guest. However, it can only be attempted once, so if it fails or if you get the fingerprint wrong, you will need to refresh this page and restart the whole procedure again. The HTML/QR code is specific to the connection attempt, you cannot reuse it!
And as mentioned in Caveats, Firefox has different behavior based on the media.peerconnection.ice.obfuscate_host_addresses in about:config. So you might want to set this to false while trying the demo, or try a different browser instead. Note that it is a global setting, so remember to set it back to the default true when you are done.