Wednesday, May 28, 2014

Websockets in Java EE 7 with wildfly

In the past few weeks I've trying the websockets technology introduced in JEE 7 and I would like to share you how to develop a simple example of it, for those who don't know what is about websockets, here is a brief introduction.

Wikipedia says "WebSocket is a protocol providing full-duplex communications channels over a single TCP connection", this means that in a client-server communication the client as the server can send a message leaving behind the request-response protocol, where the exchange is always initiated by the client (usually a browser) and the server cannot send any data without the client requesting it first.

It also says "WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server application", websockets was introduced in the clients or browsers since the html5 specification, and in the Java servers since the JEE 7 version and the specification  JSR 356.

If you want to know more about websockets refer to the following links:

I'm going to use the wildfy 8 as server the open source version of jboss, you can download it from here http://wildfly.org/downloads/, and as for the IDE I'm going to use JBoss tools, you can download it from here http://tools.jboss.org/downloads/ .

To set up wildfly with eclipse you can use the following link for instructions:  http://planet.jboss.org/post/getting_started_with_jboss_tools_and_wildfly_tech_tip_5

Once you have everything installed and integrated lets start creating a websocket application.
lets create a new project, select new project and from the options presented choose dynamic web project, set the name of the project as websockets and the target runtime to wildfy 8.

The Java API for WebSocket consists of the following packages.

  • The javax.websocket.server package contains annotations, classes, and interfaces to create and configure server endpoints.
  • The javax.websocket package contains annotations, classes, interfaces, and exceptions that are common to client and server endpoints.

Now lets create a new server endpoint class, this class will receive the messages from the client and also it could send messages to the client.


From the class above notice the @ServerEndpoint annotation, it indicates the class will be a socket endpoint, it takes a string ("example") as parameter this will be the URI of the endpoint.

The methods of the class are annotated with @OnOpen, @OnMessage, @OnClose annotations, these indicate the lifecycle of endpoint here is a brief description of them:

AnnotationEventExample
OnOpenConnection opened
@OnOpen
public void open(Session session, 
                 EndpointConfig conf) { }
OnMessageMessage received
@OnMessage
public void message(Session session, 
                    String msg) { }
OnErrorConnection error
@OnError
public void error(Session session, 
                  Throwable error) { }
OnCloseConnection closed
@OnClose
public void close(Session session, 
                  CloseReason reason) { }




The endpoint now is ready to start a conversation so deploy it in wildfy and lets create a html client to communicate with this endpoint.


In the previous html file the only thing to notice is the simple script that creates a connection to the endpoint, from the url "ws://localhost:8080/websockets/example" used check the name of the application and the URI of the endpoint.

If you open the html file on browser that supports web sockets you should see the message "Web Socket is connected!!" and in the server you should see in console the message "Open session:...". This indicates that the communication has been established between the client and the server.

To now more about the WebSocket javascript interface the following link will help:
http://www.w3.org/TR/2011/WD-websockets-20110419/

Let's create a message and send it from the client to the server. To do this let's just add the following function in the javascript section of the html file.


With this function the ws variable calls the sends() method and sends the message to the server.
To call this function just add a html link and call it.


Let's test it click on the link and you should see the following message on server's console: "Received : Message to server from client, session:..."

Now to simulate a request-response communication lets return a message from the @OnMessage method in the websocket endpoint in the server.


Deploy it and test it, you should get the following sequence of messages:

  1. Browser displays "Web sockect is connected".
  2. After calling send(), server console diplays: Received : Message to server from client, session:
  3. Browser displays "Received, Response from the server"
To demonstrate full duplex communication lets send messages from the server without any request from the client. To do this, lets add and asynchronous task to send messages.



Notice that the @Stateless annotation has been added to the endpoint, it is required to send messages asynchronously, with this now the endpoint is also an EJB, also the endpoint makes use of the ManagedExecutorService resource, it takes runnables and executes them, this is done on the @OnOpen method so when the conversation starts the runnables are set.
In the runnable we wait for 10 seconds and then sends a message to the client this is done without receiving any previous message and this is repeated 3 times so during 30 seconds, your browser should be receiving the message "Received, Message from server".

With this is demonstrated the full-duplex communication this is a message can be sent without any prior message or request.

Well this is basically a simple example that demonstrates how web sockets work, in further post I will keep showing more of their functionality.  





4 comments:

  1. Really cool article, but perhaps you want to make a small tiny adjustment and replace "JEE" with "Java EE"? :-)

    ReplyDelete
    Replies
    1. Glad you like it man! and you are right i'll change it.

      Delete
  2. Now I have one doubt. Is it possible to connect to websocket from a Java Swing Desktop Application.?

    ReplyDelete
  3. Hi,
    Sure you can access websockets in a swing application, but you need to do it with the help of a client api like:
    http://www.eclipse.org/jetty/documentation/current/jetty-websocket-client-api.html
    or
    https://tyrus.java.net/


    ReplyDelete