Wicket in Action

Wicket 6 Native WebSockets

05 July 2012, by martin-g

Asynchronous communication with Web Sockets

Wicket 6.0 introduces two new modules, both of them related to Server Push technology, Wicket-Atmosphere and Wicket Native WebSockets. In this article we will see how to make your application more dynamic by employing Wicket Native WebSockets.

Web Sockets

Web Sockets are new technology, part of HTML5 stack, for asynchronous communication between the web server and the browser. The client initiates a WebSocket connection by using the JavaScript APIs and from there on both the client and the server may send data to the other party fully asynchronously.

Wicket Native WebSocket

Server side APIs

Wicket Native WebSocket module provides an integration that makes it as easy to use WebSockets as you already use Ajax in your Wicket applications. Basically all you need to do is to add a WebSocketBehavior to a page/component and override the callback methods you may be interested in - onConnect, onClose and/or onMessage.

add(new WebSocketBehavior() {

  @Override protected void onMessage(WebSocketRequestHandler handler, TextMessage message) {
    String msg = message.getText();
    // use the message sent by the client

    handler.push("A message pushed by the server");
  }

});

Most probably an application will need to push messages from the server to the client asynchronously, i.e. without the client to ask for such messages. This may be achived by storing the needed information to lookup the WebSocket connection when WebSocketBehavior#onConnect(ConnectedMessage) is called:

@Override protected void onConnect(ConnectedMessage message) {
    applicationName = message.getApplication().getName();
    sessionId = message.getSessionId();
    pageId = message.getPageId();

    // store applicationName, sessionId, pageId somehow so they are available later
}

Later when you need to push a message asynchronously you may lookup the connection with:

IWebSocketConnectionRegistry registry = new SimpleWebSocketConnectionRegistry();
  Application application = Application.get(applicationName);
  IWebSocketConnection wsConnection = registry.getConnection(application, sessionId, pageId);

  if (wsConnection != null && wsConnection.isOpen()) {
    wsConnection.send("Asynchronous message");
  }

Client side API

By default when WebSocketBehavior is used Wicket will open a default WebSocket connection for you, so you can just use:

Wicket.WebSocket.send("A message sent by the client");

to send a message from the client to the server.

To listen for messages pushed by the server you have to subscribe for a topic with name '/websocket/message':

Wicket.Event.subscribe("/websocket/message", function(jqEvent, message) {

    // do something with the message.
    // it may be a text or a binary message depending on what you pushed from the server side
});

Re-rendering components

If you have noticed earlier #onMessage() receives a parameter of type WebSocketRequestHandler. This request handler implements AjaxRequestTarget so it is possible to add components (via #add(Component...)), to prepend/append JavaScript (via #prependJavaScript() and #appendJavaScript()) as you already do with Ajax behaviors.

@Override protected void onMessage(WebSocketRequestHandler handler, TextMessage message) {

    handler.add(someComponent);
}

Demo application

At Martin Grigorov's GitHub repository you may find an application that demonstrates some of the new possibilities available with WebSockets. The application schedules an asynchronous task at the server side that pushes data back to the client and visualizes it in Google Line chart.

Documentation

More complete documentation may be found at the Wiki. Feel free to contribute to make it better. Just create an account and edit it!

-->