The objective.
The objective of demo is to show how information can be delivered to browser clients in real time using XMPP/BOSH technique.The functionality.
The demo application gives prospective clients ability to subscribe to one or more (imaginary) weather stations and receive (made-up) weather alerts in real-time. The client can subscribe/unsubscribe to/from any of available weather stations. The subscription will be associated with client's account and used for the future sessions, so the client is required to register account first time she's using the demo.NOTE: You may use existing shared account (username: shared, password: shared) in case you do not wish to register. Registering is safe, though, as it creates a Jabber account on local domain, which is not accessible from outside. If you decide to use shared account, expect other people to alter your subscriptions. You may actually watch someone turning your subscriptions on and off, which represents a nice case of real-time collaboration :-)
Visual representation and controls.
Right-hand panel contains weather station locations organized as country -> region -> city hierarchy. The icon next to station location denotes its subscription status, as follows:
Clicking on station name will send request to turn subscription on/off for the logged in client.
Middle panel contains weather updates, one per subscribed station. Once update is received from the station, corresponding section will show up. Only last update is shown. The client can click on any section to unfold detailed information about last update received from the station.
- client is not subscribed to the station;
- client is subscribed to the station;
- the request to turn subscription on/off has been sent to the server.
- the request to turn subscription on/off has been sent to the server.
Clicking on station name will send request to turn subscription on/off for the logged in client.
Middle panel contains weather updates, one per subscribed station. Once update is received from the station, corresponding section will show up. Only last update is shown. The client can click on any section to unfold detailed information about last update received from the station.
The moving parts (architecture, that is :-).
On the client side we have HTML page that employs Strophe.js library. Strophe provides communication with XMPP server using BOSH protocol.
On the server side:
On the server side:
- ejabberd - XMPP server;
- weazard - Erlang application that acts as XMPP component, using gen_component implementation; it exposes weather stations for the service discovery and manages subscription requests by routing weather updates to subscribers;
- weather update generator - generates weather alerts every 15 seconds by randomly choosing weather station, temperature and condition.
The flow.
The client signs in, triggering Strophe to start service discovery procedure by sending "disco" requests to weazard in order to find out what weather stations are available. Strophe then receives "disco" responses through its callbacks and builds the treeview that reflects weazard's service structure (i.e. country->region->city hierarchy that resides on the right-hand panel). After the treeview has been finished, Strophe advertises client's presence, which in turn triggers XMPP server to route presence to all client's subscribed stations. As stations' addressing includes weazard's JID as host, weazard takes over and sends presence from each of subscribed stations back to Strophe. Strophe then uses presence callbacks to show subscription state (all those red and green "transmission" icons in right-hand panel and message sections in middle panel) for all discovered stations in the client's view.
From this moment on, Strophe listens to weather alert messages and updates corresponding sections in the middle panel as they go.
On the server side, weazard receives alerts from weather update generator, turns them into XMPP messages and routes them to subscribers via XMPP server.
Advantages of using XMPP/BOSH web vs. traditional web frameworks.
The most obvious advantage is a real-time interaction. This doesn't directly have to do with XMPP, but rather is provided by BOSH protocol. Very similar techniques have been around for quite some time, for instance, Comet or pushlets. BOSH is currently supported by most well-known XMPP server, which makes it natural to use with XMPP.
Another important thing is ability to reuse XMPP server features. For instance, there is no need to have separate database of registered users and their subscriptions, as this is already maintained by XMPP server. All changes in user's presence (i.e. logged in/out, disconnected) and component presence (restart, disconnection etc.) are also taken care of. It is possible to easily implement IM features, such as live support or chat between users.
XMPP/BOSH also enables asynchronous messaging style. This means that the code that submits the request will never block on waiting for the response; instead the response will be handled by a callback function. In practical terms, this makes web application more responsive and user friendly. Technically, the same behavior can be implemented without XMPP, it's just that asynchronous messaging is a natural way of life for XMPP, as opposed to a web server that is more accustomed to sequential "request-response" interactions.
Another important thing is ability to reuse XMPP server features. For instance, there is no need to have separate database of registered users and their subscriptions, as this is already maintained by XMPP server. All changes in user's presence (i.e. logged in/out, disconnected) and component presence (restart, disconnection etc.) are also taken care of. It is possible to easily implement IM features, such as live support or chat between users.
XMPP/BOSH also enables asynchronous messaging style. This means that the code that submits the request will never block on waiting for the response; instead the response will be handled by a callback function. In practical terms, this makes web application more responsive and user friendly. Technically, the same behavior can be implemented without XMPP, it's just that asynchronous messaging is a natural way of life for XMPP, as opposed to a web server that is more accustomed to sequential "request-response" interactions.
Word of caution.
Although the demo has some things done right, in case you decide to reuse the code, you should be aware that the approach being used for serving subscriptions is not suitable for every situation. Let me explain: if 500 clients will subscribe to a single weather station, the component will send 500 nearly identical XML messages to the Jabber server every time the update happens. This is not good, and should rather be implemented with PubSub or MUC. If, on the other hand, you have one-to-one subscription (say, client wants to get updates from her Twitter account), then you're fine.
I will keep fixing bugs and adding new features to the demo. Your feedback is most welcomed.
I've been trying to check out your svn repo but it always fails on images
ReplyDeletesvn: In directory 'web/images/weather'
svn: Can't open file 'web/images/weather/.svn/tmp/text-base/26.PNG.svn-base': No such file or directory
svn fixed, not sure what it was, just rechecked problem files, looks good now. Please let me know if problem persists.
ReplyDeleteregarding your "word of caution-this is not good,and should rather implemented in pubsub or muc" . arent the demo already using xmpp pubsub extension?
ReplyDeleteNo, technically there is no pubsub-compliant code in this demo. All is done with very straightforward messaging. As of now, after I've tried exmpp and ejabberd pubsub implementation, I think I'll wait a little more until it'll be more documented - too many questions that is hard to find answers to...
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDelete