Recently, I was asked to implement a feature which involved sending
notifications from the server to the client about the state of a server
resource (in my case Database). Till now, we were doing a poll once in every
four seconds to get the job done. Before we started development, we outlined
the set of requirements so that we could work towards them.
- Update all connected clients about the state of the server via
Broadcast.
- Pick a framework which doesn’t involve any external server.
- Integrate seamlessly with existing application.
- Be easy to implement and be scalable.
Once we had the set of requirements clear, we embarked on the process
of identifying the framework that would fit the bill. We (each one of us tried a poc with different technologies) evaluated Node.js,
Vert.x, ActiveMq and Atmosphere.
We chose Atmosphere since it satisfied most of our requirements.
- Doesn't require any external server.
- Has a jersey module which integrates seamlessly with any webapp.
- Switches back to the fallback transport if the browser/server doesn’t
support the specified transport.
At a high level, the POC has the following components:
- Atmosphere's server side component which takes care of suspending the
incoming request and broadcasting the data back to the clients when invoked.
- Atmosphere's client side component which is responsible to initiate a
request and handle the response it receives via the broadcaster.
- A rest resource and a client(for testing purpose) which takes care of generating the content that needs
to be broadcasted.
- BroadcastFilters which intercept the broadcast before it is being sent
to the clients.
- Interceptors which intercept the incoming requests.
- EventsLogger which logs the Framework related events like onSuspend,
onPresuspend, onReconnect, etc.
The POC, per say, is pretty straightforward. I have borrowed the
concepts from several sample programs that the author himself has shared. What's
more interesting is the number of problems that ran into during the process of
developing the POC and testing it.
Issues that I faced:
- In our project we have tomcat servers which host the application and
there is Apache Httpd 2.4 to take care of Authenication via ldap. Apache 2.4
doesn't support websockets by default so the request did not get through. I had
to upgrade the server from 2.4 to 2.4.6 which has the module mod_proxy_wstunnel
which supports websockets.
- After upgrading Apache, I had issues with IE8. IE8 doesn't support
websockets and the framework downgrades the transport to long-polling (IE8
supports long-polling). In spite of this the request didn't get through. The
client tries to establish a connection until it reaches the max no. of retries
and eventually errors out.
- Assume that a client tries to subscribe for a topic to which he doesn't
have access. So, I tried to return the response back to the client without
suspending the request with this message – "Access restricted. You don’t have
sufficient privileges to receive updates for this topic."
- I couldn't get the cache working. When the client loses connection to a
server, the broadcasted messages go into the cache and when the client resumes
connection, the messages get delivered to the client from the cache.
- Open 3 browsers Safari, Firefox and Chrome. Each has three tabs opened. Open
the application and hit subscribe on the three tabs one after the other. You
could see that the connection gets shared. Meaning, there is only one websocket
connection that gets opened and it gets shared between tabs in each browsers.
This is due to the shared attribute in the request which we set to true. Now, I
run the Rest client which pushes the data to the application which in turn
broadcasts it to the clients. Only the active tab receives the broadcasts. Not
sure if it's the intended behaviour but it does happen.
Please try this out and let me know if it works. :)
My Dev environment:
Ubuntu 12.04 and Windows 7
Browsers:
Firefox 22.0
Chrome Version 28.0.1500.95 m
Safari : 5.1.7 for Windows
Step 1: Deploy the application and open it in any of the browser.
Step 2: Choose a topic from the drop down. As of now, the FeedRestResourceClient publishes only content for the topic 'Computers & Technology'.
Step 3: Run the FeedRestResourceClient
Step 4: You'll see that the client has received the broadcast.
My Dev environment:
Ubuntu 12.04 and Windows 7
Browsers:
Firefox 22.0
Chrome Version 28.0.1500.95 m
Safari : 5.1.7 for Windows
Step 1: Deploy the application and open it in any of the browser.
Step 2: Choose a topic from the drop down. As of now, the FeedRestResourceClient publishes only content for the topic 'Computers & Technology'.
Step 3: Run the FeedRestResourceClient
Step 4: You'll see that the client has received the broadcast.
Reference Links:
~ cheers.!