WebSocket with Java (Simple HelloWorld ChatApp using websocket and atmosphere in java)

Hello all ! Today i am going to introduce and share my knowledge and findings on 'How to integrate Websocket in Java'.
Here we w'll start with a simple chat app using websocket and java. Before we start make sure that your browser and server supports websocket. In this example i am using two well known browsers and a server that supports Websockets.
Firefox Setup 17.0.1
Google.Chrome (latest version)
apache-tomcat-7.0.30
First of all let's look at the application structure to better understand the sample application.


Now let me show you all library files that i have used to make it working , please add those files in your lib folder before you start.


Now lets start adding all required files one by one to our project structure .
src\com\javaguys\help\Message.java

package com.javaguys.help;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Message {
 public String author = "";
 public String message = "";
 public Message() {}
 public Message(String author, String message) {
  this.author = author;
  this.message = message;
 }
}

   

src\com\javaguys\help\ResourceChat.java

package com.javaguys.help;

import org.atmosphere.annotation.Broadcast;
import org.atmosphere.annotation.Suspend;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/")
public class ResourceChat {
	@Suspend(contentType = "application/json")
	@GETpublic
	String suspend() {
		return "";
	}

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

   

src\com\javaguys\help\Response.java
   	
package com.javaguys.help;

import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;

@XmlRootElementpublic
class Response {
	public String text;
	public String author;
	public long time;

	public Response(String author, String text) {
		this.author = author;
		this.text = text;
		this.time = new Date().getTime();
	}

	public Response() {
	}
}
now we are done with adding server side code , lets add some actual stuff that w'll relate to the client side and application.

WebContent\css\style.css
   	
   	* {
    font-size: 14px;
    padding: 0px;
    margin: 0px;
}
p {
    line-height: 18px;
}
div {
    width: 1000px;
    margin-left: auto;
    margin-right: auto;
}
#content {
    font-family: tahoma;
    padding: 5px;
    background: #ddd;
    border-radius: 5px;
    border: 1px solid #CCC;
    margin-top: 10px;
    font-size: 14px;
}
#header {
    text-align: center;
    font-family: Segoe Print;
    padding: 5px;
    background: teal;
    border-radius: 5px;
    border: 1px solid #CCC;
    margin-top: 10px;
    color: white;
}
#input {
    border-radius: 2px;
    border: 2px solid #ccc;
    margin-top: 10px;
    padding: 5px;
    width: 890px;
}
#status {
    width: 88px;
    display: block;
    float: left;
    margin-top: 15px;
    font-size: 14px;
}

   

WebContent\jquery\application.js
   	
   	$(function() {
            "use strict";
            var content = $('#content');
            var input = $('#input');
            var status = $('#status');
            var myName = false;
            var author = null;
            var logged = false;
            var socket = $.atmosphere;
            var request = {
                url: document.location.toString() + 'chat',
                contentType: "application/json",
                logLevel: 'debug',
                transport: 'sse',
                fallbackTransport: 'long-polling'
            };
            request.onOpen = function(response) {
                content.html($('<p>', {
                    text: 'Application connected using ' + response.transport
                }));
                input.removeAttr('disabled').focus();
                status.text('Choose name:');
            };
            request.onMessage = function(response) {
                var message = response.responseBody;
                try {
                    var json = jQuery.parseJSON(message);
                } catch (e) {
                    console.log('This doesn\'t look like a valid JSON: ', message.data);
                    return;
                }
                if (!logged) {
                    logged = true;
                    status.text(myName + ': ').css('color', 'blue');
                    input.removeAttr('disabled').focus();
                } else {
                    input.removeAttr('disabled');
                    var me = json.author == author;
                    var date = typeof(json.time) == 'string' ? parseInt(json.time) : json.time;
                    addMessage(json.author, json.text, me ? 'blue' : 'black', new Date(date));
                }
            };
            request.onClose = function(response) {
                logged = false;
            }
            request.onError = function(response) {
                content.html($('<p>', {
                    text: 'Sorry, but there\'s some problem with your ' + 'socket or the server is down'
                }));
            };
            var subSocket = socket.subscribe(request);
            input.keydown(function(e) {
                        if (e.keyCode === 13) {
                            var msg = $(this).val(); // First message is always the author's name if (author == null) {  author = msg; } subSocket.push(jQuery.stringifyJSON({  author : author,  message : msg })); $(this).val(''); input.attr('disabled', 'disabled'); if (myName === false) {  myName = msg; } }});function addMessage(author, message, color, datetime) { content.append('<p><span style="color:'  + color  + '">'  + author  + '</span> @ '  + +(datetime.getHours() < 10 ? '0' + datetime.getHours()   : datetime.getHours())  + ':'  + (datetime.getMinutes() < 10 ? '0' + datetime.getMinutes()   : datetime.getMinutes()) + ': ' + message + '</p>');}});
   

we have two more js files to add up here , because of more number of lines i am not able to paste the code here.
WebContent\jquery\jquery.atmosphere.jsWebContent\jquery\jquery-1.7.2.js
these two are well known js files and can be downloaded from internet . please add these two files at related place. if you are not able to find these files please mail me , i w'll send you the files asap.
WebContent\WEB-INF\web.xml
   	


   Oodles Chat App
   Oodles Chat App
   
      AtmosphereServlet
      AtmosphereServlet
      org.atmosphere.cpr.AtmosphereServlet
      
         com.sun.jersey.config.property.packages
         com.javaguys.help
      
      0
   
   
      AtmosphereServlet
      /chat/*
   

   

WebContent\index.html
   	
<!DOCTYPE html><script type="text/javascript" src="jquery/jquery-1.7.2.js"></script><script type="text/javascript" src="jquery/jquery.atmosphere.js"></script><script type="text/javascript" src="jquery/application.js"></script>
<link rel="stylesheet" type="text/css" href="css/style.css">
<html>
   <head>
      <meta charset="utf-8">
      <title>Java Guys | Simple Chat App</title>
   </head>
   <body>
      <div id="header">
         <h3>Java Guys | Simple Chat App using Websocket !</h3>
      </div>
      <div id="content"></div>
      <div> <span id="status">Wait! Connecting...</span> <input type="text" id="input" disabled="disabled" /></div>
      <div id="header">
         <span>
            <h3>Happy Coding !</h3>
         </span>
         <span></span>
      </div>
   </body>
</html>
   
Now we are all done with adding all files to app, now start your server and if your server and browsers support websocket you w'll see something like these screens.

web-socket-atmosphere-in-java

websocket-atmosphere-in-java

websocket-atmosphere-in-java

as you can see, we can assume these two browsers as two client and we are able to see quick response server without being requested by the client. That's all about implementing reverse ajax and server push using atmosphere and websocket.