Atmosphere 0.7 released: WebSocket, GWT, Wicket, Redis, XMPP, Async I/O
Atmosphere 0.7 is available! This release contains an impressive number of new functionality and bug fixes. The extensive list of fixed bugs for that release can be read here, and the new functionality are explained below
Native GWT support
Starting with 0.7, the Atmosphere-GWT project is now fully integrated into Atmosphere. That means you can add support for WebSocket/Comet to any GWT application. You can download demos from here.
Wicket Support
As described here, we do support the Wicket framework our of the box. As simple as:
public class PushPage extends WebPage
implements AtmosphereResourceEventListener {
private final AtomicBoolean scheduleStarted = new AtomicBoolean(false);
public PushPage() {
HttpServletRequest req = getWebRequestCycle()
.getWebRequest().getHttpServletRequest();
Meteor meteor = Meteor.build(req);
if (!scheduleStarted.getAndSet(true)) {
meteor.schedule(new Callable<String>() {
public String call() {
String s = new Date().toString();
return s;
}
}, 1); // One second
}
meteor.addListener(this);
// Depending on the connection
String transport = req.getHeader("X-Atmosphere-Transport");
meteor.suspend(-1, !(transport != null
&& transport.equalsIgnoreCase("long-polling")));
}
public void onBroadcast(AtmosphereResourceEvent
<HttpServletRequest, HttpServletResponse> event) {
String transport = event.getResource()
.getRequest().getHeader("X-Atmosphere-Transport");
if (transport != null
&& transport.equalsIgnoreCase("long-polling")) {
Meteor meteor = Meteor.lookup(event.getResource().getRequest());
meteor.removeListener(this);
meteor.resume();
}
}
...
}
you can download the demo here.
Native Redis Support
As described here, you can now use Redis for massively distribute server sides events amongst your Atmosphere application. This is as simple as configuring Atmosphere to use the RedisBroadcaster to broadcast server sides events. If you already have an Atmosphere application, you don’t need to change anything except configuring Atmosphere. You can switch from your in memory broadcaster, JMSBroadcaster, JGroupsBroadcaster by simply doing:
// JSMBroadcaster || XMPPBroadcaster
private @PathParam("topic") RedisBroadcaster topic;
@GET
public SuspendResponse subscribe() {
return new SuspendResponse.SuspendResponseBuilder()
.broadcaster(topic)
.outputComments(true)
.addListener(new EventsLogger())
.build();
}
@POST
@Broadcast
public Broadcastable publish(@FormParam("message") String message) {
return new Broadcastable(message, "", topic);
}
you can download the demo here.
Native XMPP Support
As described here, you can now use the XMPP protocol for massively distribute server sides events amongst your Atmosphere application. As with Redis and JMS, you just need to tell Atmosphere to use the XMPPBroadcaster. You can download the demo here.
Broadcasting Callable<T> now supported
As described here, you can now broadcast Callable, which gets executed just before the response is written back to the browser. This is quite useful when scheduled tasks are needed:
if (feed.getAtmosphereResources().size() == 0) {
Future<?> future = feed.scheduleFixedBroadcast(new Callable<String>() {
private final AtomicReference<String> refreshUrl
= new AtomicReference<String>("");
public String call() throws Exception {
String query = null;
if (!refreshUrl.get().isEmpty()) {
query = refreshUrl.get();
} else {
query = "?q=" + tagid;
}
asyncClient.prepareGet(
"http://search.twitter.com/search.json" + query)
.execute(new AsyncCompletionHandler <Integer>()) {
@Override
public Object onCompleted(Response response)
throws Exception {
String s = response.getResponseBody();
JSONObject json = new JSONObject(s);
refreshUrl.set(json.getString("refresh_url"));
feed.broadcast(s).get();
return response.getStatusCode();
}
});
return "OK";
}
}, 1, TimeUnit.SECONDS);
futures.put(tagid, future);
}
you can download the demo here.
WebSocket Emulator Supported (like Flash)
The Atmosphere JQuery Plugin can now be configured to use an external WebSocket implementation. As an example, you can use the web-socket-js library, which adds support for Flash.
<script type="text/javascript" src="web_socket.js"></script>
<script type="text/javascript">
$(document).ready(function()
{
.....
/* transport can be : long-polling, streaming or websocket */
$.atmosphere.subscribe(uri,
myEventCallback,
$.atmosphere.request =
{transport: getElementByIdValue('transport'),
webSocketImpl: new WebSocket(uri) });
Asynchronous write I/O operation now supported
All the Broadcaster has been modified to support asynchronous I/O write operation using a dedicated ExecutorService. This will prevent slow clients to block the entire broadcast process. You can configure the thread pool strategy using the BroadcastConfig API:
Per Request BroadcastFilter
As described here, per request BroadcastFilter are now supported. That means you can transform an events based on some request’s headers, query string etc. This is quite useful when it is time to unify browser support, or take advantage of some browser native API. As simple as:
public class JavascriptClientFilter implements PerRequestBroadcastFilter {
private final AtomicInteger uniqueScriptToken = new AtomicInteger();
@Override
public BroadcastFilter.BroadcastAction filter
(HttpServletRequest request, Object message) {
if (request.getHeader("User-Agent") != null) {
String userAgent =
request.getHeader("User-Agent").toLowerCase();
if (userAgent != null && userAgent.indexOf("MSIE") != -1
&& message instanceof String) {
StringBuilder sb = new StringBuilder
("<script id=\"atmosphere_")
.append(uniqueScriptToken.getAndIncrement())
.append("\">")
.append("parent.callback")
.append("('")
.append(message.toString())
.append("');</script>");
message = sb.toString();
}
}
return new BroadcastFilter.BroadcastAction
(BroadcastFilter.BroadcastAction.ACTION.CONTINUE, message);
}
Improved Dependency Injection Support for Spring and Guice
With 0.7 we have added new API to allow easier integration with Spring and Guice. You can download the demo here.
New Broadcaster’s Lifecycle Policy Support
Broadcaster implementation like the JMSBroadcaster can hold open connections and before 0.7 it was difficult to decide what to do with those connections when no WebSocket/Comet connections where alive. We have added a new API that allow an application to configure Atmosphere and decide when a Broadcaster’s resource get garbage collected. As simple as:
Broadcaster.setBroadcasterLifeCyclePolicy( IDLE | IDLE_DESTROY | EMPTY | EMPTY_DESTROY | NEVER );
Improve compatibility with other JavaScript Framework
It is now easier to integrate the Atmosphere JQuery Plugin with other framework like Prototype.
Jersey’s @DefaultValue and @Singleton now supported
You can now use these two annotations with Atmosphere’s object like Broadcaster. As simple as:
More WebContainer supported
Atmosphere 0.7 now support all flavor of Jetty 7 and 8 Websocket implementation, as well a GlassFish v3.1 WebSocket API. Tomcat 7 Servlet 3.0 implementation works also perfectly well.
Broadcaster new API
The Broadcaster API has been heavily improved and you can now look up per request Broadcaster and also you can configure Atmosphere to broadcast value when a resume operation occurs, etc. All new features are available to all Broadcaster. See the API for more information
What’s next
The Atmosphere 0.8 release should happens before the summer and will include Socket.IO support, Google App Engine channel support, Cometd 2.2.x support, unified Atmosphere Client Javascript library and of course all the requests asked by the community.
For any questions or to download Atmosphere Client and Server Framework, go to our main site, use our Nabble forum, follow the team or myself and tweet your questions there! You can also checkout the code on Github.


Hi Jeanfrancois,
nice work, thx!
Maybe i found a bug in the jQuery-atmosphere plugin:
On long-polling registered callbacks will not beeing invoked if no ‘parent.callback’ text-phrase is found in response body. Maybe there is an missing else-branch which simply invokes the callback with the response (same behaviour like in streaming#onmessage-handling).
jquery.atmosphere.js, line 258:
if (response.responseBody.indexOf(“parent.callback”) != -1) {
// some code
}
should be:
if (response.responseBody.indexOf(“parent.callback”) != -1) {
// same code
} else {
jQuery.atmosphere.invokeCallback(response);
}
=> then: all my webapps are working again…
Another Question: Works the ‘parent.callback’-approach also in chunked stream scenarios? As i started my notification extension (http://code.google.com/p/atmosphere-notificationfw-prototype/) i tested some streaming scenarios and got some problems on parsing chunked streams. Maybe the nextIndexOf(“‘)”) is not yet part of the response… Also, what happens if “‘)” is part of the content message? In the notification-fw i solved this problem with some workarounds and a length-property (see: http://code.google.com/p/atmosphere-notificationfw-prototype/source/browse/trunk/webroot/index.html#44).
Regards,
Danilo
Salut,
just send me a diff on users@atmosphere.java.net so I can see and quickly test your required changes.
Thanks!
– Jeanfrancois
Sorry, but… Where I can found a example of a client-side use of meteor?
I started a new project, made a implementation of MeteorChat, using the example, but I can’t see a example of HOW create a client-side program… I can use a Java program to access the MeteorChat? Or I can use javascript? Can u send me a example of this cases?
Hi Jeanfrancois,
In ‘Improved Dependency Injection Support for Spring and Guice’ you mentioned that there’s a demo for download “here”. Can you clarify the URL?
Thanks,
Sean