Recently I discovered the web socket capabilities of the Tomcat web container. I read a gist by chitan. This was a nice start, but not a complete solution. Some changes were made to the tomcat classes and I don’t really like the one class to contain everything structure. Therefore I set out to create my own solution.
The sample is the most basic chat client that you can create. When loading the page a socket connection is opened. When closing the page the socket connection is closed. The client makes use of standard html5 browser support.
If you want to learn more, continue by clicking the more link
Source code
All the source code is in the following gist
https://gist.github.com/jettro/5995045
Building using maven
Finding the right dependencies is easy with something like maven. You need to provide two libraries. I used tomcat version 7.0.42
org.apache.tomcat:tomcat-catalina org.apache.tomcat:tomcat-coyote
Creating the servlet
We have to create a subclass of WebSocketServlet. We have to implement one method in the subclass called createWebSocketInbound(…). In this method we create our instance of a MessageInbound subclass. We also initialize the ClientsRepository. The servlet is mapped in the web.xml.
The inbound message handler
The inbound message handler is created in the servlet when a new client connects. The class itself is very basic, we have an onOpen and an onClose method that add or removes the client from the repository. This class also contains the onTextMessage method that uses the repository to send the received message to all connected clients.
The clients repository
This class maintains a list of connected clients. It also contains the method to send a message to all those connected clients. The following code blocks shows that method.
public void sendMessageToAll(CharBuffer message) { try { for (ChatMessageInbound client : clients) { CharBuffer buffer = CharBuffer.wrap(message); client.getWsOutbound().writeTextMessage(buffer); client.getWsOutbound().flush(); } } catch (IOException e) { e.printStackTrace(); } }
Check in the code that we loop over all clients write a text message and after that do a flush to send the message to the client.
The client
The final bit is the client that uses the index.html page to load the page and the required javascript to make the connection, respond to incoming messages and to send messages to the server. The next code block shows the involved JavaScript
var ws = new WebSocket("ws://localhost:8080/wschat/WsChatServlet"); ws.onopen = function(){ }; ws.onmessage = function(message){ document.getElementById("chatlog").textContent += message.data + "\n"; }; function postToServer(){ ws.send(document.getElementById("msg").value); document.getElementById("msg").value = ""; } function closeConnect(){ ws.close(); }
We first create the connection, then we have methods for receiving a message, sending a message and closing the connection.
Concluding
Now it becomes easy to use WebSockets when deployed on Tomcat. Of course there are alternatives for jetty and other containers. Now a days there is even a jsr for all this. Watch this blog for more items to come in that area.