WebSockets – A Quick Introduction and a Sample Application

AT IDR Solutions I spend alot of time working with Glassfish which runs our Online PDF to HTML5 Converter so it is important for me to keep up to date with the latest technology.

I thought it might be useful to take a look at WebSockets which is a relatively new technology which promises to make websites more reactive by allowing lower latency interaction between users and the server. In this series of articles I’ll show you some sample applications you can build using WebSockets and Java EE7.

What is WebSocket?

WebSocket is a protocol which allows for communication between the client and the server/endpoint using a single TCP connection. Sounds a bit like http doesn’t it? The advantage WebSocket has over HTTP is that the protocol is full-duplex (allows for simultaneous two-way communcation) and it’s header is much smaller than that of a HTTP header, allowing for more efficient communcation even over small packets of data.

The life cycle of a WebSocket is easy to understand as well:

  1. Client sends the Server a handshake request in the form of a HTTP upgrade header with data about the WebSocket it’s attempting to connect to.
  2. The Server responds to the request with another HTTP header, this is the last time a HTTP header gets used in the WebSocket connection. If the handshake was successful, they server sends a HTTP header telling the client it’s switching to the WebSocket protocol.
  3. Now a constant connection is opened and the client and server can send any number of messages to each other until the connection is closed. These messages only have about 2 bytes of overhead.

A Simple Example

The WebSocket API was introduced with Java EE7, in this example we’ll create a client which will send a message to the server and the server will send it back.

For this example I’ll be using the NetBeans 7.4 and the Glassfish 4 server, which comes bundled with NetBeans.

Setting up the Project

Open the New Project Wizard, choose Java Web and select Web Application. Select next, name your project and choose it’s save location and press next.

New Project

Make sure your chosen server is the name of your GlassFish server and that the Java EE version you’re working with is 7 and press finish.
Web Configuration

 Your project should now be generated. Now, we’ll build the Server Endpoint which will handle incoming WebSocket messages.

In your project go to “Source Packages” and create a new Java class. The server endpoint is a Plain Old Java Object (POJO) which uses Java’s annotations to define it’s methods (This can be done programmatically but looks much cleaner using annotation). This is the code for the endpoint:

import java.io.IOException;
 
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
 
/** 
 * @ServerEndpoint gives the relative name for the end point
 * This will be accessed via ws://localhost:8080/EchoChamber/echo
 * Where "localhost" is the address of the host,
 * "EchoChamber" is the name of the package
 * and "echo" is the address to access this class from the server
 */
@ServerEndpoint("/echo") 
public class EchoServer {
    /**
     * @OnOpen allows us to intercept the creation of a new session.
     * The session class allows us to send data to the user.
     * In the method onOpen, we'll let the user know that the handshake was 
     * successful.
     */
    @OnOpen
    public void onOpen(Session session){
        System.out.println(session.getId() + " has opened a connection"); 
        try {
            session.getBasicRemote().sendText("Connection Established");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
 
    /**
     * When a user sends a message to the server, this method will intercept the message
     * and allow us to react to it. For now the message is read as a String.
     */
    @OnMessage
    public void onMessage(String message, Session session){
        System.out.println("Message from " + session.getId() + ": " + message);
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
 
    /**
     * The user closes the connection.
     * 
     * Note: you can't send messages to the client from this method
     */
    @OnClose
    public void onClose(Session session){
        System.out.println("Session " +session.getId()+" has ended");
    }
}

And the code for the client, which goes into the index.html. In the project view navigate to Web Pages and open index.html this should be some generic HTML. I will be using HTML/Javascript to control the client side. There is a standard API for WebSockets in JavaScript and is supported by most modern browsers. In index.html replace the code with the following:

edit: As pointed out in the comments, the undefined connection appears to be a bug in certain browsers.

All that’s left to do now is run the server. In NetBeans right click the project directory and select run, this will start up Glassfish and deploy the application to the server. Your default browser should now open a new page where you can start using the client above. To open the connection press open, type something into the text box and press send. When your done press the close button.

Your client should look something like this:

helloworld

And to prove it’s not just smoke and mirrors, here’s the output from the server, the hex string shown is the ID of the client:

serverside

And there you have it, how to create a simple Echo application using web sockets in Java EE7. In my next article, I’ll use WebSockets to transport more important information, images of our pets.

Got any comments or questions? Leave them below.

This post is part of our “GlassFish Articles Index” series. In these articles, we aim to explore GlassFish in different ways, from useful tutorials, to JaveOne and general.

If you would like to read more articles on Servers you should try:

If you want to trying running Java Software on the Amazon Cloud you can try following these handy tutorials

If you’re a first-time reader, or simply want to be notified when we post new articles and updates, you can keep up to date by social media (TwitterFacebook and Google+) or the  Blog RSS.

Related Posts:

The following two tabs change content below.
Simon Lissack is a developer at IDR Solutions, working on JavaFX, Android and the Cloud Conversion service.
Simon

About Simon Lissack

Simon Lissack is a developer at IDR Solutions, working on JavaFX, Android and the Cloud Conversion service.

30 thoughts on “WebSockets – A Quick Introduction and a Sample Application

  1. diego

    your brief tutorial would be even better if you explained other important details, like, for example, why the endpoint will be accessed on ws://localhost:8080/WebSocketTest/websocket

    Thanks.

    • Thanks for the suggestion, I’ve added it to the article. I also noticed it should be /echo and not /websocket and updated it.

  2. Hey, Simon, thanks for that answer. I have learned a few interesting things thanks to your tutorial.

    Probably you have already seen this (but just in case):
    http://stackoverflow.com/questions/12170230/why-do-i-get-two-connections-from-websocket-client-one-is-empty

    I have been playing with your example (with minor modifications) and found that Chrome (Version 36.0.1985.125) opens two websocket connections (one undefined) but on Safari (Version 7.0.5 (9537.77.4)) it doesn’t do so, so you might have an explanation to what you were experiencing on your websocket.onopen (you were requesting a comment if anybody had a clue, so here might be a hint 🙂 ).

    Thanks again for this tutorial.

    • That’s very interesting, thanks again 🙂

  3. Syz

    Does this work on Tomcat 7 or does it work only with Glassfish?

    • it should work on Tomcat too, if you are running java EE 6 or above

      • Irshad

        Not running with Tomcat 7 (J2EE 6), but works perfectly with Tomcat 8(J2EE 7)

  4. kiwi

    // For reasons I can’t determine, onopen gets called twice
    // and the first time event.data is undefined.
    // Leave a comment if you know the answer.

    it is undefined because that is no “event.data” for the json return from handle websocket.open.

    you can use this

    console.log(event);

    to see what it is return. I test on chrome 38.0.2125.111 m

  5. Shashank

    This is not working with Eclipse + Apache Tomcat , I Created dynamic project in eclipse , is there any configuration required for this , please help ? I’ve attached the war , you can directly import in eclipse and it works let me know .

    https://www.dropbox.com/s/9fx8icah8v6kmsi/WebSocketWebApplication.war?dl=0

    • Dear Shashank
      if you could let us know the version of apache tomcat server you are running then we can reproduce the problem and give you a solution

  6. Can you please.
    Give me a simple project client and server socket
    Thank you

  7. habib

    Dear Simon,

    I’m trying out websockets and thought your samples are a good starting point. I could not get the html code, could you please fix the issue at your earliest convenience.

    Thank you !!!

    • Dear Habib
      what type of error you are experiencing? can’t you access the html code? have you tried in new browsers?

  8. Venkatesan

    I am getting connection close error,I am using mozilla updated version

    • what server and java ee version you are running ?

    • what server and what java EE version you are running ?

  9. Rocketfish

    Very clear tutorial but I’m also experiencing the connection closed problem using:

    eclipse luna
    Java 1.7
    tomcat7

    I tried some suggestions I found in doing some research with no luck:

    1. set the connection timeout to -1 to keep it open
    2. don’t use bio connector protocol, use nio instead

    Here is the part of server.xml that accomplishes both yet it still doesn’t work:


    <!– –>

    Any help would be appreciated.

    • Rocketfish

      server.xml
      ————–


      <!– –>

      • Rocketfish

        port=”8080″
        protocol=”org.apache.coyote.http11.Http11NioProtocol”
        connectionTimeout=”-1″

        • Hi Rocketfish, we will investigate this issue on Eclipse Luna and come back to you with a solution.

  10. MilanG

    Great tutorial/example, but I run into some problems – can you please help me. I’m using Eclipse Luna. I created dynamic web project (what ever that is?). After that I had to manually add to build path “javaee-api-7.0.jar” lib. After that eclipse is not reporting me any errors. But when I run the project in console I get message:

    Starting preview server on port 8080

    Modules:
    EchoChamber (/EchoChamber)

    2015-02-21 11:06:04.996:INFO:oejs.Server:jetty-8.1.14.v20131031
    2015-02-21 11:06:05.543:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080

    On front-end JS just says “Connection closed”. When I open “http://localhost:8080/” from browser I get:


    Error 404 - Not Found
    No context on this server matched or handled this request.
    Contexts known to this server are:

    EchoChamber(/EchoChamber)

    Where last word is a link and when I click it I get new page:


    Directory: /EchoChamber/
    META-INF/ 0 bytes Feb 21, 2015 10:49:23 AM
    WEB-INF/ 0 bytes Feb 21, 2015 10:49:23 AM

    and both of those 2 dirs are empty..

    • I am afraid we use NetBeans and IDEA inhouse.

  11. MilanG

    Installed Net Beans and it’s working well….So, don’t bother for me to solve this Eclipse problem. But in case you think it would be interested for other folks…
    Thanks for the great tutorial!

  12. Bharat

    How many connections can be supported by the “javax.websocket” at one time? I mean what is the maximum number of users can chat simultaneously?

    • As far as i know there is no limit ( the web socket connections are actually sessions ) but you can confine the connections and session limit in servers.

  13. Talha Khan

    Hello Sir,

    I follow your instructions and copy paste your code but I couldn’t get the server response. In HTML between 3 buttons (Open, Send, Close) only open is working and it only return “Connection close” whenever i pressed it.

    • Could you give us details such as : Server name and version, browser name and version

  14. Nandhagopal

    Hello sir,
    Open should click “connection close” only work it. I’am using GlassFish Server 4.1 and JEE 7 to used.. Please give the solution. Thankyou…

  15. yaser

    Hi
    I have a problem in creating connection.
    i am using Glass Fish and Net Beans. When I press “open” button an error occur in “OnError” that say: “connection closed” and event.data is undefined!!!
    Why Do I have this notification?

    • yaser

      OK….
      I got it….
      Cheek the ws://localhost:8080/EchoChamber/echo in your HTML page
      Cheek that the EchoChamber…. and your IP Address is correct…

Comments are closed.