Web Socket Communication using jWebSocket
Web Socket has been introduced in HTML5 to enable full duplex communication with minimum network traffic and latency. I was working on a PoC on HTMl5 Web Socket. In this blog I am sharing my experience about working with jWebSocket to get the basic WebSocket communication running. jWebSocket is pure Java/JavaScript based implementation for implementing Web Socket communication. After reading this blog the readers should be able to send asynchronous request from client through Web Socket and get response from the server. This blog assumes that readers have basic knowledge of HTML5 Web Sockets
HTML 5 Web Socket specification defines an API that enables full duplex communication over one (TCP) socket. Before web sockets the server could respond only on receiving a request from a web client. To overcome this limitation the common workarounds are polling, long polling and comet based solutions. HTML 5 Web Sockets comes as an inbuilt support for bi-directional communication which promises to be highly scalable due to reduced network traffic and latency.
In this blog I have used jWebSocket the Web Socket implementation for Java/JS. The first step is to download the required distribution files from jWebSocket.org and follow the steps for configuration.
To get the Web Socket communication running both client and server side coding efforts are involved. I will deal with both of them. Let us start with the client side code
The jWebSocket distribution comes with jWebSocket.js which needs to be included in your view file. Basically the jWebSocket.js exposes the JS implementation for WebSocket. The following steps are to be followed to make the client interact with the server through Web Sockets.
- Create an instance of jWebSocketJSONClient.
- Create a WebSocket connection.
- Send/Receive tokens.
Step 1: Create an instance of jWebSocketJSONClient: jWebSocket exposes clients like jWebSocketJSONClient, jWebSocketCSVClient, jWebSocketXMLClient. For our example we will use jWebSocketJSONClient. As a first step I have written initWebSocket function which checks if the browser supports HTML5's WebSocket and only then creates an instance of the jWebSocketJsonClient.
var jWebSocketClient = null;
function initWebSocket(){
if( jws.browserSupportsWebSockets() ) {
jWebSocketClient = new jws.jWebSocketJSONClient();
} else {
var lMsg = jws.MSG_WS_NOT_SUPPORTED;
}
}
Step 2: Create a WebSocket connection - Once it is ascertained that the browser supports Web Sockets and the jWebSocketClient is created then logon() function of the client can be invoked to create a physical WebSocket connection between the client and the server. The function takes the url, username, password and the callback functions as the argument.
- url - represents the end-point to which you wish to connect. Please note that the url starts with ws:// and not http:// as the Web Socket connection is established using the Web Socket protocol. Web Socket protocol is an upgrade over HTTP protocol using the same underlying TCP/IP connection. ws:// and wss:// prefix are proposed to indicate a WebSocket and a secure WebSocket connection, respectively.
- username / password - The user details can be configured in jWebSocket.xml which is packages in conf folder of the jWebSocket server deployment directory. All the authentication details by default will be validated against this file.
- callback functions - WebSocket interface has attribute functions onOpen, onClose, onError and onMessage. Whenever we create a Web Socket connection we can provide callbacks for the Web Socket connection open and close events, an error event and a message receive event. When ever any of these events occur the corresponding call backs will get called allowing you to handle the situation.
function logon(){
var lRes = jWebSocketClient.logon( "ws://hostname|localhost:8787",
"username", "password", {
// OnOpen callback
OnOpen: function( aEvent ) {
log( "jWebSocket connection established." );
},
// OnMessage callback
OnMessage: function( aEvent, aToken ) {
log( "jWebSocket '" + aToken.type + "' token received, full message: '"
+ aEvent.data);
},
// OnClose callback
OnClose: function( aEvent ) {
log( "jWebSocket connection closed." );
}
});
}
Step 3: Send/Receive tokens - Once the connection request is authenticated and the socket connection is established both the client and server can send information to each other whenever they want. To send token from the client just create a token with namespace and type. Remember that the client being used to send data is JSON client and therefore the token should follow the JSON format. Once the token is ready, invoke the send method of the JSON client which takes token and the callback function (which will be invoked if the server sends some response) as arguments.
function sampleListener() {
if( jWebSocketClient.isConnected() ) {
log("sending message to jwebsocket");
var lToken = {
ns: "my.namespace",
type: "getInfo"
};
jWebSocketClient.sendToken( lToken, {
OnResponse: function( aToken ) {
log("Server responded: "
+ "vendor: " + aToken.vendor
+ ", version: " + aToken.version
);
}
});
} else {
log( "Not connected." );
}
}
Let us look into the server side code, all the requests related to Web Sockets are handled by Web Socket server. The following steps are required to be followed to make the server Web Socket enabled
- Start the jWebSocket server and register a JWebSocketTokenServerListener with the jWebSocketServer
- Create a Listener implementation of JWebSocketTokenServerListener and provide the implementation (this is the listener which was registered with the server int the previous step)
Step 1 : Start the jWebSocket server and register a JWebSocketTokenServerListener with the jWebSocketServer : When the application starts up in the application server it has to be ensured that the jWebSocket server also starts up. To ensure this a listener of type ServletContextListener can be configured in web.xml. I have created a JWSContextListener and configured the listener in web.xml as below.
<listener>
<description>ServletContextListener</description>
<listener-class>com.checkList.web.contextUtils.JWSContextListener</listener-class>
</listener>
jWebSocketServer is started in the contextInitialized method of JWSContextListener. To be able to receive tokens and resopond to certain events in the jWebSocketServer a listener JWebSocketListener is registered to the token server. The listener registered to the server will listen to the events occurring in the sever and the corresponding methods will get called. In jWebSocket.xml in conf folder of the jWebSocket server deployment you can specify the server types to be instantiated for jWebSocket. Each server type has a unique id. By default token server and custom server are defined with ids as ts0 and cs0 respectively. That is why there is reference to ts0 in "TokenServer tokenServer = (TokenServer)JWebSocketFactory.getServer("ts0");."
<pre>public class JWSContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// start the jWebSocket server sub system
JWebSocketFactory.start("");
TokenServer tokenServer = (TokenServer)JWebSocketFactory.getServer("ts0");
if(tokenServer !=null){
tokenServer.addListener(new JWebSocketListener());
}
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
JWebSocketFactory.stop();
}
}
Step 2 : Create a Listener implementation of JWebSocketTokenServerListener and provide the implementation : The JWebSocketListener implements the WebSocketTokenListener and provides the implementation. Once a token is received by the client the processToken method will be invoked. The other life cycle methods will similarly respond to the corresponding events. If we further look into the processToken() method, the WebSocketServerTokenEvent is injected as an argument. WebSocketServerTokenEvent has a createResponse method which takes token as argument and creates a response token. Once the responseToken is ready, it is sent using the sendToken method of WebSocketServerTokenEvent object. This is how server sends back the response.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; line-height: 19px; white-space: normal; font-size: 13px;"> <pre style="font: normal normal normal 12px/18px Consolas, Monaco, 'Courier New', Courier, monospace;">[sourcecode language="java"] public class JWebSocketListener implements WebSocketServerTokenListener{ @Override public void processToken(WebSocketServerTokenEvent serverTokenEvent, Token token) { // here you can interpret the token type sent from the client according to your needs. String tokenNameSpace = token.getNS(); String tokenType = token.getType(); // check if token has a type and a matching namespace if (tokenType != null && "my.namespace".equals(tokenNameSpace)) { // create a response token Token tokenResponse = serverTokenEvent.createResponse(token); if ("getInfo".equals(tokenType)) { // if type is "getInfo" return some server information tokenResponse.setString("vendor", "JWebSocket"); tokenResponse.setString("version", ".10"); tokenResponse.setString("copyright", "JWebSocket.org"); tokenResponse.setString("license", "No Liscense"); tokenResponse.setString("Demo Text", "This is demo text"); } else { // if unknown type in this namespace, return corresponding error message tokenResponse.setString("code", "-1"); tokenResponse.setString("msg", "Token type '" + tokenType + "' not supported in namespace '" + tokenNameSpace + "'."); } serverTokenEvent.sendToken(tokenResponse); } } @Override public void processClosed(WebSocketServerEvent arg0) { } @Override public void processOpened(WebSocketServerEvent event) { System.out.println("***********Client '" + event.getSessionId() + "' connected.*********"); } public void sendPacket(){ } @Override public void processPacket(WebSocketServerEvent arg0, WebSocketPacket arg1) { } } [/sourcecode] Please refer to following links to read more about Web Socket |
Please refer to following link to read more about jWebSocket
In my next blog, I will discuss how to implement the data push from the server.




[...] If reader is more interested in getting started with WebSocket you may read the blog – Web Socket Communication Using jWebSocket. [...]
[...] Xebia Blog article on getting started with jWebSocket: http://xebee.xebia.in/2010/10/05/web-socket-communication-using-jwebsocket/. [...]
Can you post .zip file of example.
Nice article and very helpful. Unfortunately I’m stuck with jWebSocket at a very basic stage. I can’t get the sample clients to work when I load from the same system on which I’m running my jWebSocket server The server keesp dropping the connections indicating that there is a problem with the connection handshaking.
When I inquired about this with the jWebSocket dev team I was told it most likely had to do with the domain not be set up properly, yet I see statements in my jWebSocket.xml config file for 127.0.0.1. There is no documentation that I could find on the jWebSocket website showing how to configure the jWebsocket.xml file properly.
Do you have any suggestions? Thanks in advance.
– vic
Hello, nice tutorial indeed.
Appreciate if you upload whole sample project for more reference.
Thanks in advance.
Hi,
Is there any API in jWebSocket that will help to connect the tomcat websocket from java stand alone client.