Home > Atmosphere, Comet, JQuery, Websocket > Atmosphere 0.8: Jersey on Steroid, WebSocket Sub Protocol, Native WebSocket, JQuery Plugin CORS, REST over HTTP

Atmosphere 0.8: Jersey on Steroid, WebSocket Sub Protocol, Native WebSocket, JQuery Plugin CORS, REST over HTTP

The Atmosphere Framework 0.8 version has been released. This is our biggest release ever! This blog will describe the new feature covered by this fantastic release.

Jersey on Steroid with WebSocket

The Jersey Framework can now be fully run on top of a WebSocket connection seamlessly. A single WebSocket connection can now be used to invoke Jersey. That’s open the door to request pipeline and asynchronous processing of REST call transparently. This will be discussed soon in more details, but this feature is implemented via the new WebSocketProtocol API.

Browser WebSocket Support

Atmosphere fully support Opera, Firefox (MozWebSocket), Chrome, Safari and IE 10 Preview WebSocket transparently when used with the Atmosphere JQuery Plug In. Safari on iOS is also supported.

Native WebSocket Support

It is now possible to write native WebSocket application. A simple PubSub application can consist only of:

    public AtmosphereRequest onMessage(WebSocket webSocket, String message) {
        AtmosphereResource r = (AtmosphereResource) webSocket.resource();
        Broadcaster b = lookupBroadcaster(r.getRequest().getPathInfo());

        b.broadcast(message);

        //Do not dispatch to another Container
        return null;
    }

    public void onOpen(WebSocket webSocket) {
        // Accept the handshake by suspending the response.
        AtmosphereResource r = (AtmosphereResource) webSocket.resource();
        Broadcaster b = lookupBroadcaster(r.getRequest().getPathInfo());
        r.setBroadcaster(b);
        r.addEventListener(new WebSocketEventListenerAdapter());

        // Keep Alive the WebSocket Connection Forever
        r.suspend(-1);
    }

    public void onClose(WebSocket webSocket) {
        webSocket.resource().resume();
    }

    public void onError(WebSocket webSocket,
                        WebSocketProcessor.WebSocketException t) {
        logger.error(t.getMessage() + " Status {} Message {}",
                     t.response().getStatus(),
                     t.response().getStatusMessage());
    }

WebSocket Sub Protocol Implementation Support

Writing WebSocket sub protocol on top of a WebSocket connection is now extremely simple, thanks to the WebSocketProtocol API

public interface WebSocketProtocol extends AsyncProtocol{

    /**
     * Allow an implementation to query the
     * AtmosphereConfig of init-param, etc.
     */
    void configure(AtmosphereServlet.AtmosphereConfig config);

    /**
     * Parse the WebSocket message, and delegate the processing
     * to the {@link org.atmosphere.cpr.AtmosphereServlet#cometSupport} or
     * to any existing technology. Invoking
     * {@link org.atmosphere.cpr.AtmosphereServlet#cometSupport} will
     * delegate the request processing
     * to the {@link org.atmosphere.cpr.AtmosphereHandler} implementation.
     * Returning null means this implementation will
     * handle itself the processing/dispatching of the WebSocket's request;
     * /
    AtmosphereRequest onMessage(WebSocket webSocket, String data);

    AtmosphereRequest onMessage(WebSocket webSocket, byte[] data, int offset, int length);

    /**
     * Invoked when a WebSocket is opened
     * @param webSocket {@link WebSocket}
     */
    void onOpen(WebSocket webSocket);

    /**
     * Invoked when a WebSocket is closed
     * @param webSocket {@link WebSocket}
     */
    void onClose(WebSocket webSocket);

    /**
     * Invoked when an error occurs.
     * @param webSocket {@link WebSocket}
     * @param t a WebSocketProcessor.WebSocketException
     */
    void onError(WebSocket webSocket, WebSocketProcessor.WebSocketException t);

By default, Atmosphere uses the SimpleHttpProtocol to dispatch WebSocket message to Servlet based container. As an example, Atmosphere dispatch WebSockets messages to Jersey by wrapping the message inside an HttpServletRequest and  an asynchronous I/O HttpServletResponse. By default message are considered as POST when dispatched to Jersey, but all HTTP property are configurable (content-type, headers, cookies, etc.). Another example is the EchoProtocol, which just echo message to all connected WebSocket.

Improved Cross-Origin Resource Sharing (CORS) Support

The Atmosphere JQuery Plug In has an improved support for CORS, specially with IE 8/9. You can either turn it on globally or per request. As simple as:

                    jQuery.atmosphere.subscribe(
                        this.url,
                        this.atmosphereCallback,
                        jQuery.atmosphere.request = {
                            method : 'POST',
                            data : json,
                            transport: "websocket" ,
                            fallbackMethod: "POST",
                            enableXDR : 'true', 
 attachHeadersAsQueryString: true });

Trackability Support and Multi Tab

Trackability of remote AtmosphereResource was available in previous version only with Jersey. With 0.8, Trackability is now available to all modules and natively implemented in the JQuery Atmosphere Plug In. When the Plug In execute a request, a unique ID is assigned to the request. The server will read that unique id and will try to look up an AtmosphereResource linked to that ID. That allow application to remotely manipulate AtmosphereResource without the need to keep track, inside the application itself, a list of AtmosphereResource. That allow an application to suspend more than one AtmosphereResource per connection, opening the possibility to implement Browser multi-tab support by assigning a unique ID per tab, represented by different AtmosphereResource on the server side.

Atmosphere also support Trackable injection like:

  @Path("/subscribe")
  @POST def subscribeAndPublish(
    @HeaderParam(X_ATMOSPHERE_TRACKING_ID) trackedResource: 
                    TrackableResource[AtmosphereResource[_, _]],
    @HeaderParam(X_ATMOSPHERE_TRACKING_ID) trackingID: String,
    @HeaderParam(X_ATMOSPHERE_TRANSPORT) transport: String, message: String)
            : SuspendResponse[TrackableResource[AtmosphereResource[_, _]]] = 
    {
     ....
    }

Headers as Query String

Some environment are just allowing the GET operation. An example if the WebSocket Handshake operation, which by default execute a GET without allowing the client to configure any headers. IE CORS also only support this model. The good news is Atmosphere can encode the headers as a QueryString and decode it on the server side as header, allowing application to pass information during the handshake operation. As simple as:

                    jQuery.atmosphere.subscribe(
                        this.url,
                        this.atmosphereCallback,
                        jQuery.atmosphere.request = {
                            method : 'POST',
                            data : json,
                            transport: "websocket" ,
                            fallbackMethod: "POST",
                            attachHeadersAsQueryString: true

                        });

There is much more new features, take a look at the changes log for more info.

For any questions or to download Atmosphere Client and Server Framework, go to our main site, use our Google Group forum, follow the team or myself and tweet your questions there! .

About these ads
Categories: Atmosphere, Comet, JQuery, Websocket
  1. Nor
    December 7, 2011 at 12:55 am

    Hi Jean, I’m currently looking at Atmosphere, will possibly use it for web chat app.

    Now the scenario will be, client sitting on host1 will subscribe to channel on host2. Through that channel he will get messages from other users, he will be sending his messages by posting to some different url on host2.

    Is it possible to reuse subscribed connection to make those posts (as urls are different) ? So to use it for receiving broadcasts but at the same time be sending ajax calls? The reason is to reuse the existing connection and not care about sending requests especially to other domain.

    As client and server will be different hosts, there’s a need to enable cross domain requests. Does Atmosphere support any other method than CORS to achieve this? I thought that if I set transport to jsonp, it will work, but no luck there. If I subscribe to different host using jsonp transport, i see in firebug streaming connection opens, i even see how the response is gradually built by jsonp calls originating from broadcasts, but my callback for that subscription is never called …

    Thank you for your help …

  2. MJF
    December 26, 2011 at 8:43 pm

    Hi Jeanfrancois,

    I’m prototyping a streaming feed using atmosphere, and it seems to be working well. I do have one concern with the general comet approach and I was wondering if you had any advice. Is there a way to monitor the response stream of a suspended connection to make sure that the client is actually reading data off of it? If a client is still connected but not reading off of the response stream, continuing to broadcast data eventually causes memory problems and I’d like to proactively terminate those. There’s nothing obvious in the Java/J2EE API surrounding HttpServletResponse and IO streams that’s jumping out at me.

    Thanks in advance!

    • January 11, 2012 at 4:07 pm

      Salut,

      sorry for the delay. Next time if you can, post to atmosphere-framework@googlegroups.com. When you say memory problems, are you seeing OOM? It goes down to the container you are using IMO (Atmosphere isn’t doing anything, it just write and assume the container will take care of it). If you have a test case I can look at, feel free to share.

      Thanks!

      – Jeanfrancois

  1. December 9, 2011 at 1:07 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 51 other followers

%d bloggers like this: