Experimenting with serverless apps

Servers are inherent to the web. The recent unhosted movement tends to reduce their importance to give the power back to the client applications.

But is a completely serverless web really achievable?

Let's stay very basic for now and let's not consider issues like security or version update.

(Note: the content of this post was inspired and developed during an event and a hack day I attended recently.)

A dystopian example

Imagine you are demonstrating against the government in place in your country. They are powerful and control the communication. In order to slow and confuse you they cut all network. Without internet you can't communicate with your peers and can't organise the movement.

You want to be able to send and receive information. How can you do that when all you have is a web enabled device and no network?

Distribute serverless apps

Let's see if it's possible to distribute apps from device to device, using web technologies only but without servers.

file:// URI scheme

The most obvious and direct approach is to create a file on your computer and open it in your browser using the file:// protocol. It works for simple documents but comes with a huge list of limitations:

Data URI

Data URIs allow to package all of your app logic and resources in a string format that your browser can recognise and execute. Rather than using a URL as a reference to a content located somewhere, the URL contains everything. The address IS the content.

A very simple example is the following: data:text/html;utf-8,<b>Hello, world!</b>

Clicking on the link will display the text "Hello, world!" in bold. Everything is self-contained.

There is a limitation, however, in the number of characters such a URI can contain: no more than 65535. Here is the function I use to convert HTML code to data URI:

function dataUriEncode(string) {
  var encoded = 'data:text/html;utf-8,' + encodeURIComponent(string);
  if (encoded.length >= 65535) {
    console.error('The string generated is too long.')
  }
  return encoded;
}

Abusing data Uris

Let's now abuse this simple mechanism to create web pages and distribute them without server.

For the sake of an example, I shamelessly stole WOLF1K, a clone of Wolfenstein in JavaScript that only weights 1K. Here is the complete source code of the app that I'll try to distribute:

data:text/html;utf-8,<title>WOLF1K</title><canvas id=c></canvas><script>E="A=document.body.children.c;B=A.getContext('2d'~=1$&31$&992(E&19)?1;    n=@nB#[A#)onkeyup=0};D=[setInterval(@=innerWidth-30;A.heigh@/2;    n=@n=[t,n,S,8+$*S&8)|(X+y+t*s+t*c8&7]){w=X=x=;v=y=;z=2]z+n/@ a=s=yG=F,r=u;a=c=X    ;$~)F<G?(F,F1/uS=c/u):(G,G1/rS=32*s/r)}    n=@i<15;i++){2];j=38;i?1X=(+,;Y=(,+;ji?random(8-42]=(b-t/16+9.42%6.28)-3.14;z-atan2(Y-=v,X-=w~i&&>.5?=[sqrt(X*X+Y*Y),@/2-@*b,i,0,++n]    D.sort(+x[-y[}~n)    a=[,a/@ F=@/2//[,c=8,u=v=+1=[3]=c=1,@,0%)'):a!ca)    '+v+'%)'atob('CBF+/p6f9AC9bsP/w/dqvdvb2NvD29sb'),y=8,@/4,b!yb)d>>y&1,v),9)]";"@A.widthMath.cos(b)B[i][function(x,y){B.fillStyle='hsl('+D[n][2]+'1,99%,%=1;u=a<0?-a:a,F=(a<0?d:1-d)/u;onkeydownMath.sin(b).charCodeAt(x++%73)    for(?B.fillRect(a,b,u:A[j]-A[j+2];D[n]A[x.which]=--;*t/8;x|=y<<5;,i=0;Math.+=0]1.1,return)*b=,d=:0}F/41]t= -.5,!-=F;#[n]=$(x~);,x".replace(/.([%-}]+)/g,function(x,y){E=E.split(x[0]).join(y)});eval(E)</script>

I will now run this web page and distribute it to other devices without using a server. The tests below are based on the following browser/OS configuration:

Feel free to test and send me the results on other OS configurations.

Distribution strategies

Link

This is the easier way of sharing a data URI app and it works everywhere! Just click the link below to start the app: WOLF1K

Obviously a link means that a web page is required and possibly a server to host it.

Emails

I haven't been able to send or receive a data URI link from an email. This is due to security reasons. What works though is to paste the source code of the app and ask the recipient to copy and paste it in her browser address bar.

SMS

Likewise, copy/pasting content from a text message is the only way to use SMS to send such an app.

Bluetooth and NFC

This methods were a major disappointment to me. I was really hoping that one can send a data URI app from a device to another. But it doesn't work due to "Can't open media type" (Bluetooth) and "Unknown tag type" (NFC) errors. That said, I suspect it can be fixed on Firefox OS.

QR Code

1084 characters are too much for QR Code and make it impossible to decode.

This is sad because this prevents us from using printed material to distribute apps.

If you don't believe me, try to scan that: WOLF1K

Wifi Direct

This is a protocol to discover and communicate with devices connected to the same Wifi network, even if there is no Internet connection. Though it is currently implemented in Firefox OS and Android, this needs to be tested to see if it's possible to send data URI web app via this channel.

Bookmarking and adding to homescreen

Once the app received is running on your browser, you want to bookmark it so that you can use it later.

Desktop browsers permit bookmarking data URI apps, but not to add to homescreen.

On mobile browsers, things are slightly more complex:

So what now?

Ironically the only methods that work are the server based one (link, email, text messages). Distributing web documents encoded in data URI without a server is a bit tricky at the moment. OS UI don't always allow creating, sharing or opening such apps. I understand this falls in a particular edge case, but if data URI apps were supported like URL based apps, things would be easier.

Now I'd love to see a discussion happening around what does the web need to achieve this. Are they any specifications currently being standardised that would go in this direction?

Let's move things forward and get a truly serverless web!

Comments

Google Play Music on Firefox OS

Unfortunately, HTML5 playback of Google Play Music doesn't work in Firefox desktop, let alone Firefox OS.

The only workaround on desktop is to deactivate HTML5 Audio (and enable Flash!) in Settings > Lab:

How to deactivate HTML5 audio in Google Play Music Settings

The reasons why HTML5 playback doesn't work is probably because of browser sniffing. A couple of bugs are opened (Google Play Music HTML5 Audio Feature broken and Google Play Music not working on Firefox for Android/Firefox OS), but no clear solution was provided thus far.

I'm using Google Play Music to play my CD collection that I've encoded over the last few years and I want listen to it on Firefox OS.

JavaScript API? Nay

There are no official APIs, but some unofficial ones are available. The risk of relying your product on unofficial API is that it can stop working because of a redesign or a protocol change of the original service. Before consider this as an option make sure to check how is the maintainer committed to the API maintenance!

I'm not enquiring further in this direction because a server is usually required. I want something that works offline.

Offline mode? Yay

So, here's how I use Google Music on my Firefox OS devices:

I get:

I don't get:

It's completely disconnected to the Google Music account, so whenever I upload new CDs, I have to download and copy them to the SD card. But to be honest I don't really mind and it works for me: I get the album covers and it works offline!

Firefox OS Play app showing albums imported from Google Music

Comments