Archive

Archive for the ‘Uncategorized’ Category

The Atmosphere Framework 2.0 released

The Async-IO dev team are pleased to announce the release of The Atmosphere Framework 2.0! You can download it here

Besides all of the performance and cache memory improvements made between Atmosphere 1.0, version 2.0 comes with a host of improvements and new features. Probably the biggest improvement that our users will notice is much better memory usage under high load and improved WebSocket/fallbacks transport performance. This changes alone makes it worth upgrading!

Read the announcement here!

Categories: Uncategorized

wAsync: WebSockets with Fallbacks transports for Android, Node.js and Atmosphere

wAsync aims to make realtime apps possible in Android’s mobile device and Java/JVM clients communicating with framework like Node.js and Atmosphere, blurring the differences between the different transport mechanisms. Transports supported are WebSockets, Server Side Events, Long-Polling and Http Streaming. You can download all samples from wAsync’s main page.

wAsync is really simple to use. For this blog, let’s write a simple chat using Node.js. First, let’s define a super simple Node.js WebSockets server with static files support. I’m dropping the entire code here assumining you know how Node.js works.

Now let’s write a wAsync’s Android client that can communiate with this server. Graphically, it will looks like

Screen Shot 2013-04-04 at 10.49.26 AM

Pretty simple Android application

As with for the Node.js server, I assume you are familiar with Android development.

Now let’s explain the code. First, we create a new client (line 19)

Client client = ClientFactory.getDefault().newClient();

Next, let’s create a Request to send:

RequestBuilder request = client.newRequestBuilder()
   .method(Request.METHOD.GET)
   .uri(serverIpAddress)

This demo is using JSON, and we want to use Jackson for marshalling/unmarshalling Java POJO. So just we define a really simple Encoder:

.encoder(new Encoder<Data, String>() {
           @Override
           public String encode(Data data) {
              try {
                return mapper.writeValueAsString(data)
              } catch (IOException e) {
                throw new RuntimeException(e);
              }
           }
})

This code will be invoked before the message is sent to Node.js and will covert the POJO to JSON. Next we define a decoder that will handle Node.js’s JSON response. We only decode messages, we aren’t interested by other events wAsync propagates:

.decoder(new Decoder<String, Data>() {
           @Override
           public Data decode(Transport.EVENT_TYPE type, 
                              String data) {
 
             if (type.equals(Transport.EVENT_TYPE.MESSAGE)) {
                try {
                   return mapper.readValue(data, Data.class);
                } catch (IOException e) {
                }
             }
             return null;        
})

Next, we create our Socket to Node.js (line 49)

final org.atmosphere.wasync.Socket socket = client.create();

And define two functions, one for handling the message, one for handling unexpected exceptions, and finally open the Socket

socket.on("message", new Function<Data>() {
           @Override
           public void on(final Data t) {
               uiHandler.post(new Runnable() {
               @Override
               public void run() {
                 Date d = new Date(t.getTime());
                 tv.append("Author " + t.getAuthor() + "@ " 
                   + d.getHours() + ":" + d.getMinutes() + ": "
                   + t.getMessage() + "\n");
                  }
              });
            }
            }).on(new Function<Throwable>() {
                @Override
                public void on(Throwable t) {
                    tv.setText("ERROR 3: " + t.getMessage());
                    t.printStackTrace();
                }
        }).open(request.build());

Finally, we just display what we are receiving on the Android screen:

  bt.setOnClickListener(new OnClickListener() {

           String name = null;
           public void onClick(View v) {
               try {
                 EditText et = (EditText) findViewById(R.id.EditText01);
                 String str = et.getText().toString();
                 if (name == null) {
                   name = str;
                 }
                 socket.fire(new Data(name, str));
                 et.setText("");
                 Log.d("Client", "Client sent message");
               } catch (Throwable e) {
                 tv.setText("ERROR " + e.getMessage());
                 e.printStackTrace();
                }
            }
       });

That’s all. If you want to chat between Android and a browser, you can install this HTML file, which will use atmosphere.js, the Atmosphere Framework’s client side to communicate with Node.js. You can use the Javascript WebSocket API directly as well, but with atmosphere.js, you get transports fallback support for free.

Now let’s write the same client, but this time using the Atmosphere Framework instead of Node.js. wAsync supports natively the Atmosphere protocol with fallback transports like long-polling, so we can tell wAsync to use long-polling in case the server doesn’t support websockets. For the server, instead of Node.js, we use the NettoSphere server.

The full code can be browsed here. The two differences are:

AtmosphereClient client =
   ClientFactory.getDefault().newClient(AtmosphereClient.class);

Here we create a specialized client, which will allow use to set some Atmosphere’s protocol specific property:

RequestBuilder request = client.newRequestBuilder()
   .method(Request.METHOD.GET)
   .uri(serverIpAddress)
   .trackMessageLength(true)
      [...]
   .transport(Request.TRANSPORT.WEBSOCKET)
   .transport(Request.TRANSPORT.LONG_POLLING);

The track message lenght feature make sure two JSON messages are never delivered to the function as a single message. To supports that with Node.js, we would have needed to install Socket.IO.

What’s next with wAsync? Add support for both Socket.IO and SocksJs protocol. Want to contribute? Fork us! For more information, ping me on Twitter or follow the Atmosphere Framework!

The wAsync developpement is powered by Async-IO.org, the company behind the Atmosphere Framework!

Safari’s WebSocket implementation and Java: Problematic!

The current Safari version (~5.1.5 … on OS X and iOS) implements an old version of the WebSockets specifications. This old version can  cause major issues with Java WebServer  in production. Here is some recommendations to workaround Safari. Important note: my observation are based on large deployments using the Atmosphere Framework.

First, let’s take a look at Java WebServers supporting WebSockets

WebServers Version Specification Safari Stability
Tomcat 7.0.27 and up hybi-13 and up NOT SUPPORTED
Jetty 7.0 to 7.4.5 Up to hybi-12 UNSTABLE: Server suffer High CPU when Safari’s WebSocket connection get closed.
Jetty 7.5.x to 7.6.2 Up to hybi-12 UNSTABLE: Server suffer High CPU when Safari’s WebSocket connection get closed.
Jetty 7.5.x to 7.6.2 Up to hybi-13 UNSTABLE: Server suffer High CPU when Safari’s WebSocket connection get closed.
Jetty 8.x to 8.1.2 Up to hybi-13 UNSTABLE: Server suffer High CPU when Safari’s WebSocket connection get closed.
Jetty 7.6.3 All hybi version STABLE
Jetty 8.1.3 All hybi version STABLE
GlassFish 3.1.1 All hybi version UNSTABLE: Suffer many API bugs
GlassFish 3.1.2 All hybi version STABLE
NettoSphere (based on Netty Framework) 1.x All hybi version STABLE

My recommendation is if you need to put a WebSocket application in production, use Jetty 7.6.3 or 8.1.3. GlassFish is also a good server but much more heavyweight to use if you are planning to write pure WebSocket applications. NettoSphere is fairly new and until Atmosphere 1.0.0 is released, I’m not yet recommending it (yet!). Note that the Netty Framework’s WebSocket implementation can be considered a STABLE as well, but to run Atmosphere on top of it you need NettoSphere.

Now if you can’t any of the stable WebServer, you can still use WebSockets. All you need to do is to write a Servlet’s Filter that will detect the WebSocket version and force Safari to downgrade to another “transport” or communication channel. Server Sides Events, long-polling, http streaming, polling or JSONP can then be used to reconnect. You just need to implement the reconnect inside your websocket#onClose function. With Atmosphere JQuery PlugIn, the reconnect is done transparently, e./g no special code needed. The Atmosphere Filter looks like:

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String draft = filterConfig
            .getInitParameter(ApplicationConfig.WEB_SOCKET_BANNED_VERSION);
        if (draft != null) {
            bannedVersion = draft.split(",");
            logger.debug("Blocked WebSocket Draft version {}", draft);
        }
    }

    @Override
    public void doFilter(ServletRequest request, 
                         ServletResponse response, 
                         FilterChain chain) 
        throws IOException, ServletException {

        HttpServletRequest r = HttpServletRequest.class.cast(request);
        if (Utils.webSocketEnabled(r)) {
            int draft =r.getIntHeader("Sec-WebSocket-Version");
            if (draft < 0) {
                draft = r.getIntHeader("Sec-WebSocket-Draft");
            }

            if (bannedVersion != null) {
                for (String s : bannedVersion) {
                    if (Integer.parseInt(s) == draft) {
                       HttpServletResponse.class.cast(response) 
                           .sendError(501, "Websocket protocol not supported"); 
                       return;
                    }
                }
            }
        }
        chain.doFilter(request, response);
    }

So if you aren’t using the Atmosphere Framework, make sure you have some sort of Filter than will block Safari from creating problem.

If you are planning to use WebSocket and Java, I strongly recommend you look at Atmosphere instead of using private native API and get stuck on a server forever. For more information, ping me on Twitter!

Atmosphere .9 .9 .9 .9 released: Tomcat/GlassFish WebSocket, Netty Framework, Hazelcast, Fluid API, JQuery Optimization

The Atmosphere Framework version 0.9 has been released and contains a lot of new cool features and bugs fixes (around 101!!). This blog will describes the main new features! But first, let’s make it clear: the Atmosphere Framework has been designed to transparently support Comet and WebSocket with both client and server components. That means you don’t have to care if a server supports WebSocket or Comet, if a Browser supports WebSocket or not. You write your application and Atmosphere will pick the best transport for you, TRANSPARENTLY! As an example, all applications written with Atmosphere deployed on Jetty can now be deployed AS-IT-IS in Tomcat and automatically use the new Tomcat’s WebSocket API. Yes, you read it correctly: WITHOUT any changes!

Performance and Massive Scalability?

Atmosphere is live for 3 months of WSJ.com and Smartmoney.com and serves millions of requests using WebSocket, Long-Polling and JSONP => Atmosphere is production ready! And there is much more live Web Site using Atmosphere…I just can list them here.

Adoption

Atmosphere is available in mostly all available framework, either as a plugin or extension. If your framework isn’t supporting Atmosphere, complains to them and tell them it is really simple to add support!

jQuery.atmosphere.js new API

The Atmosphere Javascript client has been rewritten in order to allow a better integration with the WebSocket API  and auto detection of the best transport to use depending of server capacity. For example, atmosphere.js always try to use WebSocket as the initial transport and will transparently negotiate with the server to see which transport to use. If the server isn’t supporting WebSocket, atmosphere.js will transparently use HTTP (long-polling, streaming or JSONP). On both client and server side, your application doesn’t need to implement anything in order to work. API wise, function support has been added to make it really easy to write Javascript client. New functions available are onOpen, onReconnect, onClose, onError. As an example, a chat client supporting WebSocket and Comet will only consist of:

    var socket = $.atmosphere;
    var request = { url: document.location.toString() + 'chat',
                    contentType : "application/json",
                    logLevel : 'debug',
                    transport : 'websocket' ,
                    fallbackTransport: 'long-polling'};

    request.onOpen = function(response) {
       ...
    };

    request.onReconnect = function (request, response) {
       ...
    };

    request.onMessage = function (response) {
        var message = response.responseBody;
        ...
    };

    request.onError = function(response) {
       ...
    };

    var subSocket = socket.subscribe(request);

A lot of improvements has been made to hide Browser specific implementation: the famous Internet Explorer works transparently and supported version are 6/7/8/9 and always pick the best transport.

Native Tomcat WebSocket

Starting with Tomat 7.0.27, Atmosphere will detect the new Tomcat WebSocket API and use it by default. That means atmosphere.js will negotiate the WebSocket protocol and use it. That also means as soon as you deploy your application from previous Tomcat version to 7.0.27, WebSocket will transparently used. As an example, the chat client described above will transparently communicates using WebSocket to its associated Server component

@Path("/")
@Produces("application/json")
public class ResourceChat {

    @Suspend
    @GET
    public String suspend() {
        return "";
    }

    @Broadcast(writeEntity = false)
    @POST
    public Response broadcast(Message message) {
        return new Response(message.author, message.message);
    }
}

Now you can compare the number of line the Atmosphere Chat (support all transports) requires versus the Tomcat Chat (which, btw, only support WebSocket). Much more simpler with Atmosphere!

Netty Framework Support

YES, you read it correctly. Atmosphere has been refactored and can now be run on top of non Servlet Container! NettoSphere is the runtime that allow any existing Atmosphere application to run transparently on top of the Netty Framework. NettoSphere also support WebSocket and any existing applications will work without any change. As simple as

    Nettosphere server = new Nettosphere.Builder().config(
                 new Config.Builder()
                    .host("127.0.0.1")
                    .port(8080)
                    .staticResourcePath("/Users/jfarcand/")
                    .resource(MyResource.class)
                    .build())
                 .build();
    server.start();

GlassFish 3.1.2 WebSocket Support

The latest GlassFish release ships with an updated WebSocket implementation and Atmosphere makes use of it. As with Tomcat, Netty and Jetty, Atmosphere applications can be deployed without any modifications.

JAX-RS 2.0 Async API Support

The work in progress JAX-RS 2.0 specification introduces a new async API (which strangely looks like Atmosphere’s own API ;-)). The current incarnation of the API is really limited and I really hope the Spec EG will reconsider their decision. But whatever decision is made, Atmosphere supports the new annotation and the ExecutionContext class. The chat application would looks like

    // You can use that object to suspend as well.
    @Context ExecutionContext ctx;

    @Suspend() // Not the Atmosphere's Suspend
    @GET
    public String suspend() {
        // ctx.suspend
        return "";
    }

    @POST
    @Broadcast(writeEntity = false)
    public Response broadcast(Message message) {
        return new Response(message.author, message.message);
    }

You can compare with the current JAX-RS samples Chat, that only support long-polling (much more complex). The JAX-RS Async API lack of listener is a major issue IMO. As an example, Atmosphere’s Suspend annotation suppors event listeners which can be used to track the current state of the connection. As an example, with the current incantation of JAX-RS Async API, an application cannot be notified when a client drop the connection and hence the application’s resources can never be cleaned. That can easily produces out of memory error. Another problem is with the JAX-RS Async API it is quite complex to implement http-streaming because some browsers required some padding data before the response (WebKit and IE). In conclusion: since Atmosphere runs transparently in all WebServer, there are no good reasons to move to JAX RS 2 Async API (which will only runs on top of Servlet 3.0 WebServer). Instead use the API with Atmosphere and get portability, WebSocket and transport negotiation.

Native WebSocket Application

Atmosphere supports native WebSocket development, e.g application that only support WebSocket. A simple pubsub WebSocket will looks like

public class WebSocketPubSub extends WebSocketHandler {

    private static final Logger logger = LoggerFactory.getLogger(WebSocketPubSub.class);

    @Override
    public void onTextMessage(WebSocket webSocket, String message) {
        AtmosphereResource r = webSocket.resource();
        Broadcaster b = lookupBroadcaster(r.getRequest().getPathInfo());

        if (message != null && message.indexOf("message") != -1) {
            b.broadcast(message.substring("message=".length()));
        }
    }

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

. The client would consists of

var request = { url : document.location.toString() };

request.onMessage = function (response) {
    if (response.status == 200) {
        var data = response.responseBody;
        if (data.length > 0) {
            // print the message
        }
    }
}
subSocket = socket.subscribe(request);

You can also use the WebSocket API directly, but atmosphere.js does a lot more (reconnection, proper API use, etc.)

Hazelcast support

Atmosphere can now be clustered/clouded using Hazelcast. As simple as:

@Path("/pubsub/{topic}")
@Produces("text/html;charset=ISO-8859-1")
public class JQueryPubSub {

    private @PathParam("topic") HazelcastBroadcaster 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);
    }
}

The broadcast operations will be distributed to all Hazelcast server available. You can masively scale your WebSocket application by just using the Hazelcast plugin! Don’t like Hazelcast? You can do the same using Redis/JMS/XMPP or JGroup broadcaster as well.

Miscellaneous

Tons of new features and improvements (101 issues fixed). Amongst them

1.0.0: Coming SOON, SwaggerSocket around the corner!

Atmosphere is fully powered by Wordnik and we are working hard to make the 1.0.0 release happens soon (End of May 2012). At Wordnik we are using Atmosphere a lot and soon we will release our REST over WebSocket protocol (called SwaggerSocket, which integrate with Swagger). New features will includes an Atmosphere Java Client that will mimic the Javascript functionality, Terracotta supports, etc (see a detailed list here).

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

Async Http Client 1.2.0 released

Read the official announcement including the changes log

http://codemeself.blogspot.com/2010/10/async-http-client-120.html

Thanks to every body that contributed to that amazing release.

For any questions you can use our Google Group, on irc.freenode.net #asynchttpclient or use Twitter to reach me! You can checkout the code on Github, download the jars from Maven Central or use Maven:

<dependency>
    <groupId>com.ning</groupId>
    <artifactId>async-http-client</artifactId>
    <version>1.2.0</version>
</dependency>

Categories: Uncategorized

Leaving Ning

Today I’ve officially resigned from Ning. Ning was a wonderful place to work, but I wanted to spend more time with my three little monsters and avoid traveling to California so often. I’ve never worked in a team of skilled architects like that and I will miss all the learning I was doing every day. Thanks to all of you and I’m sure Ning will be a great success!! I hope we all keep in touch!


What I’m gonna do? My quest for my next company start this week … things may move quite fast as you all know :-) For sure I will take a couple of weeks off as I’ve left Sun on a Friday and the next Monday I was at Ning. Bad idea but I was so trilled to join a great place like Ning!

I will not disappear completely as I can’t stop improving my Atmosphere Framework and support our growwwwwing community..so I will not be 100% on vacation. I also want to explore Akka as this project is so interesting and the community there is just awesome, and i can be dangerous as I have commit access :-)! I will also continue to actively work on the Async Http Client…actually I will spend more time on it now!!.

So, Just follow me on Twitter for summer news :-).

Categories: Uncategorized

The new Atlassian JIRA Studio Activity Bar is powered by the Atmosphere Framework

Last week Atlassian released their new JIRA Studio, which is a hosted software development suite that supports every role of a high-performing development team throughevery stage of your development process.. One of the new feature is called the Activity Bar and it is powered by Atmosphere!

Atmosphere is hidding inside the  “Recent Issues” window above :-). You can read the official annoucement here and why Atmosphere was choosen instead of Servlet 3.0 or private implementation like Jetty and Grizzly.

Technically, the Activity Bar is using the atmosphere-jersey module as it makes it quite simple to write asynchronous applications: only five annotations to learn: @Suspend, @Resume, @Broadcast, @Schedule and @Cluster. As the name implies, this module build around the powerful Project Jersey and atmosphere-runtime, which is our portable layer on top of all private/non portable asynchronous Java API. The Activity Bar is also using the atmosphere-guice module (an improved version of), which bring the power of Google Guice to Atmosphere. Finally, the Activity Bar is using an API called AtmosphereResourceEventListener, which is extremely useful when writing asynchronous application. Why? Because when you suspend connections, you want to make sure all the resources associated with your connections get cleaned if the remote browser close the connection. Without such API, your application can easily produces OOM as some resources may stay associated with dead connections forever. Always think about that before choosing a Comet framework!

Wow! It has been a pleasure to work with Richard Wallace and his team. Since we are using JIRA @ Ning, I should soon work with my own framework!

For any questions or to download Atmosphere, go to our main site and use our Nabble forum (no subscription needed) or follow the team or myself and tweet your questions there! Or download our latest presentation to get an overview of what the framework is.

technorati:

Categories: Uncategorized
Follow

Get every new post delivered to your Inbox.

Join 52 other followers