Really Easy Displays Framework; looking back and lessons learned.

During my PhD work I created a framework to prototype multi-display applications using HTML5 really easitly . It was great! It helped me develop many applications for several experiments faster than any other framework at the time and taught me a thing or two.

How RED worked

If you had an input with id "txtbox", and a division with id "chat", you could a JQuery plugin to quickly declare DOM elements to be declared as "things", this set up REST AJAX listeners for common JQuery DOM modification techniques like "append" and "prepend". What this meant was that a division element with ID chat could be made interactive by (1) declaring it as a thing:

$("#chat").thing({listen:true});

This would set up a listener and act on any objects received. So the following key-press binding would sending a "prepend" event, would "prepend" a paragraph to the element "chat".

$("#txtbox").keypress(function(e){
  if (e.which == 13) {
    $(this).thing({prepend: ""+$(this).val()+"", to: '#chat'});
    $(this).val("");
  }
});

Whatever, right? Well, used in conjunction with a container application (The Cherry Container (https://github.com/ubc-magic/thingbroker-jquery-plugin) it allowed you to thread listeners to deploy at different contexts, without changing your code.

So building the chat/post-it app in the video above consisted in coding the following:

and deploying the same code at different large displays via a web interface.

Users could then approach a situated display, scan a QR Code and start interacting with your application. Interactions done at a display A (events passed to your #chat DOM object after scanning the QR Code) would only reach the application at display A.

Under the hood

Implementation of this was quite easy (as you can see here https://github.com/ubc-magic/thingbroker-jquery-plugin).

It consisted of binding JQuery events to AJAX requests made to a message broker we implemented called "Thing Broker", which allowed you to declare "things" (channels) and post data to them. Each DOM object instantiated as "thing" would set up recursive AJAX requests listening for new events, parse such events looking for familiar keys and bind the data to JQuery events.

Screenshot from 2015-06-07 01:07:30

In the case where an application was deployed inside a Cherry Container (iframe) a session ID would be used to create a child "thing" that would allow some sort of threading mechanism to separate events by session. This session was independent of any user session anywhere in the application. The Architecture was as simple as it gets:

Screenshot from 2015-06-07 01:06:18

It was good... for prototypes.

If you're familiar with web development you already figured this out. It was good to prototype small applications, but it really sucked in production. We only implemented a few JQuery listeners which limited how much we could do (and we never got to implementing more). Our implementation of the "Thing Broker" or REST-based broker was not the best, as latency in REST is sloooow, every time you make a request you need to open and close a connection and there's better ways to do it (i.e. websockets). And there's so many AJAX request you can open in a browser before hitting a limit.

Lessons learned. If we were to implement this again.

I see three main lessons learned, that today sound obvious, but a the time they didn't: leverage available (duh); REST is... just OK, DOM as worldly things makes sense (but not individually this way)

  • At the time, frameworks like "backbone" or "AngularJS", or whatever is the trendy kid on the block when you read this didn't exist. So it made sense to implement a custom solution to a custom problem. However nowadays assembling a better solution with off-the-shelf components is trivial. Many of the frameworks today has a REST component that is easy to set up and you (mostly) don't have to maintain. But if you, like me, want to learn go ahead and implement everything from scratch!
  • Today I would implement this using websockets to a MQQT broker or REDIS pub/sub component. REST is quite slow when you consider each request needs to open and close a connection. Websockets allow you bidirectional open communication, which is fast! While support for many web browsers is still in the works I expect this to change soon, and we can all stop doing long-pulling hacks. Now, don't get me wrong, REST is awesome, for things that require data to be polled once in a while, or to send data to an application occasionally it makes sense, just not for streams of data.
  • The idea of making DOM objects "things", in the most worldly sense is a great one. Soon, when everybody is trying to play catch-up with the IoT (internet of things) race and we start connecting our appliances to virtual data understanding both virtual and physical entities as part of a same ontology will make things easier. We can then connect a paragraph (social media post) to our clothing, and connect to an abstract concept of health care data, all under the same concept of "things". Then designing applications that bridge both worlds would be less painful. However not all DOM objects on an HTML document are meaningful things. That is, not all paragraph should be a thing, rather the content that is inside that paragraph is what really matters. This requires that our applications know the difference between meaningful data (for example user content) and data that doesn't matter in such a context (a division used to style the page, or advertisement content?). Food for thought...