Web Sockets, Ember and Elixir

August 7, 2014

Revisit.io is prodominatly made of Elixir and Ember.js code. It has some Node.js and Ruby code thrown in for good measure. One thing that makes it quite different/interesting is that the communication between the client and the application is done with web sockets.

Posting a bookmark in Revisit

When a user posts a bookmark in Revisit the process is broken down into:

What this actually does on the frontend is:

Using web sockets allows Revisit to skip polling for changes and just receive a push message when a bookmark is updated.

The most interesting thing here is broadcast bookmark. It works like a chat server, in that it iterates over the users who should receive the message and then sends the message to each of the open connections:

Elixir makes it really easy to persist the pid of a connection to the database so it can be associated to a user:

pid = to_string :erlang.pid_to_list(self)

And checking whether a process is still running is simple:

Process.alive?(pid)

Using send with the given pid allows you to send the data back to the socket in Elixir:

send pid, { :message, ExJSON.generate([uuid: "push", payload: App.TimelineEntriesPresenter.present(timeline_entry), type: "timeline_entry"]) }

Once data is being pushed to the client adding support for web sockets to Ember is well documented around the web.

Revisit’s implementation generates a UUID for all requests that are initiated by the client. When a request is initiated by the server a “PUSH” request is received and interpreted by the client. The data is pushed into Ember Data like so:

var payload = serializer.extract(this, type, adapterPayload, null, 'findAll');

this.pushMany(type, payload);

Ember does an amazing job of updating the screen when new data is sent and pushed into Ember Data. Using store.filter is a great way to ensure live data matches the query that was made to the server previously.

Browser gets Sleepy

When a user closes their laptop and then comes back later, they will expect the application responds normally to clicks. Even though the web socket has died (but isn’t erroring).

Luckily, it is simple to trap this in the browser and re-establish the connection.

window.addEventListener("online", establishConnection);

Join the Beta

If you like bookmarks, join the beta: Revisit.io.


Originally published at carlwoodward.com.