WebSocket tutorial with Java server (Jetty) and JavaScript client

WebSocket is a web technology providing full-duplex communications channels over a single TCP connection. WebSocket is designed to be implemented in web browsers and web servers, but it can be used by any client or server application. In this tutorial we will use a Java server and a JavaScript client.

We start with the Java server. Start by downloading the Jetty distribution files, at the time of writing the latest version was jetty-distribution-9.0.5.v20130815. Unzip this file and copy the lib directory to a place where your Java application (which we will build in a moment) can find it. Now create a Java project and start with the WebSocketTest class file:

import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;

public class WebSocketTest {

    public static void main(String[] args) throws Exception {
        Server server = new Server(8080);
        WebSocketHandler wsHandler = new WebSocketHandler() {
            @Override
            public void configure(WebSocketServletFactory factory) {
                factory.register(MyWebSocketHandler.class);
            }
        };
        server.setHandler(wsHandler);
        server.start();
        server.join();
    }
}

Now create the MyWebSocketHandler class:

import java.io.IOException;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;

@WebSocket
public class MyWebSocketHandler {

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        System.out.println("Close: statusCode=" + statusCode + ", reason=" + reason);
    }

    @OnWebSocketError
    public void onError(Throwable t) {
        System.out.println("Error: " + t.getMessage());
    }

    @OnWebSocketConnect
    public void onConnect(Session session) {
        System.out.println("Connect: " + session.getRemoteAddress().getAddress());
        try {
            session.getRemote().sendString("Hello Webbrowser");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnWebSocketMessage
    public void onMessage(String message) {
        System.out.println("Message: " + message);
    }
}

The server side of things is now done. The client is written in Javascript with some HTML to make it work. The index.html file looks like this:

<!DOCTYPE html>
<html>
    <body>
        <h1>WebSocket test</h1>
        <script src="index.js"></script>
    </body>
</html>

And the referenced index.js looks like this:

var ws = new WebSocket("ws://127.0.0.1:8080/");

ws.onopen = function() {
    alert("Opened!");
    ws.send("Hello Server");
};

ws.onmessage = function (evt) {
    alert("Message: " + evt.data);
};

ws.onclose = function() {
    alert("Closed!");
};

ws.onerror = function(err) {
    alert("Error: " + err);
};

Now startup the server side by running the main of the WebSocketTest class and startup the client by pointing your webbrowser to the index.html file. If your browser is new enough to support WebSocket, you should see that the client and the server connect with each other and that the server sends a message to the client and vice versa. On the client:

websocket-client-1 websocket-client-2

On the server:

websocket-server-1

If we wait long enough, a timeout will occur, resulting in the following message on the client:

websocket-client-3

and this on the server:

websocket-server-2

18 thoughts on “WebSocket tutorial with Java server (Jetty) and JavaScript client

  1. Permalink  ⋅ Reply

    Steven

    March 30, 2014 at 11:27am

    Thanks for sharing! There are a couple of examples for seting up a websocket server, but your’s is pretty simple and easy to begin with.

  2. Permalink  ⋅ Reply

    Sean

    April 15, 2014 at 5:21am

    can you mail me you example full android project file?
    l try form your example code, but I finally crash in phone.
    Thank you.

  3. Permalink  ⋅ Reply

    Kamesh Palani

    April 22, 2014 at 1:11pm

    Hi,

    I just followed the above instruction but, I’m getting below exception,

    ” WebSocket connection to ‘ws://localhost:8989/WS/’ failed: Error during WebSocket handshake: Unexpected response code: 200 ”

    Could some one please help me regarding the same?

    Thanks in Advance,
    -Kamesh

  4. Permalink  ⋅ Reply

    monkry

    May 7, 2014 at 6:49pm

    MY GOODNESSSSS
    Thank you so very much Sir! I’ve searched for something like this for god knows how long… many websocket and jetty example out there, but for me who’s total newbie in web programming and fucked up understanding in backend programming, a neat simple example and up-to-date (thank you very much for using Jetty 9.x…) like this is so… *sobs* Again, thank you so very much Sir! ( TvT)

  5. Permalink  ⋅ Reply

    vamshi

    June 13, 2014 at 12:20pm

    not working for android mobile(4.4 version, chrome browser).

  6. Permalink  ⋅ Reply

    Dylan

    August 25, 2014 at 1:01pm

    Got it working eventually by changing the port to 8081.
    Its as if Jetty was listening on 8080 and doing nothing with the client connection (like jetty didnt not get told of a handler).
    I wasnt running Jetty by specifying a main class, but using the “java -jar start.jar” and deploying a webapp.

    How do I run it main class method + as well as have the webapp with index.html etc deployed?
    Or do I have to split it up? Tutorial makes it sound like one deployable artefact should work.

    Still confused…unless I split it into two.

  7. Permalink  ⋅ Reply

    Ruwen

    December 19, 2014 at 5:26pm

    Thanks for the tutorial.
    It’s working for me with Chrome but not with Firefox / IE.
    Both browsers are using WebSocket Version 13.

    In FF the connection is immediately closed after it is established (@OnWebSocketConnect is called, @OnWebSocketClose immediately after it). The close reason is 1001 or sth. 1005.

    Any ideas?

    thx for help.

  8. Permalink  ⋅ Reply

    Andy C.

    January 2, 2015 at 12:08pm

    Thank you very much for your tutorial: it’s valuable and effective.

    Good job indeed!

    Andy C.

  9. Permalink  ⋅ Reply

    Andy C.

    February 11, 2015 at 2:13pm

    I’m experimenting with your code: it is very instructive, thank you again.

    A question regarding “MyWebSocketHandler” class: in your code, the Server sends a msg back to the Client inside the “onConnect” method, using “session”.
    Instead, how can I send a msg back to the Client inside the “onMessage” method? In this method, “session” seems not to be available.
    Any suggestion?

    Thank you very much for your help.

    Bye,

    Andy C.

    • Permalink  ⋅ Reply

      sergio levin

      December 29, 2016 at 5:12pm

      Use:
      @OnWebSocketMessage
      public void onMessage(Session session, String message) {
      System.out.println(“Message: ” + message);
      ModelTask task = EngineTaskFacade.getInstance().runModel(message);
      try {
      session.getRemote().sendString(“Echo”);
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

  10. Permalink  ⋅ Reply

    Florent

    April 10, 2015 at 11:31pm

    Thank you very much.

    I would just like to add the necessary maven dependencies:

    org.eclipse.jetty
    jetty-server
    9.3.0.M2

    org.eclipse.jetty
    jetty-servlet
    9.3.0.M2
    jar

    org.eclipse.jetty.websocket
    websocket-api
    9.3.0.M2

    org.eclipse.jetty.websocket
    websocket-server
    9.3.0.M2

    • Permalink  ⋅ Reply

      sergio

      December 29, 2016 at 5:11pm

      Use :
      @OnWebSocketMessage
      public void onMessage(Session session, String message) {
      System.out.println(“Message: ” + message);
      try {
      session.getRemote().sendString(“Echo”);
      } catch (IOException e) {
      e.printStackTrace();
      }
      }

  11. Permalink  ⋅ Reply

    Martin Michael Utzon

    May 13, 2015 at 4:53pm

    Hi than you for the tutorial
    I am in doubt about how to add the jetty libs. to the project
    should I
    1:rightclick/build path/configure buildpath/libraries/add library?
    2: copy paste the libs into one of my folders
    regards martin

  12. Permalink  ⋅ Reply

    Martin

    May 14, 2015 at 12:03pm

    Hi
    When I try to run the program, it cannot find the Server. I get a classnotfoundException.
    could someone please give me a clue?

  13. Permalink  ⋅ Reply

    Benedict

    November 9, 2015 at 10:41am

    Hey great example! I’m trying to get a Jetty Server to talk to Unity 5 via websocket sharp. Managed to send PNG files to the client and added them as a texture, but can’t get the darn client to send a string to request the files. Anyone come across this? I can send to the server using websocket.send (ws.send here) from a browser using javascript, but get the feeling like I need to mess around with the encoding and manually transmit packets of bytes to the server, anyway just guessing. Anyone know the format that .Send uses to transmit packages? Handshake works fine.

  14. Permalink  ⋅ Reply

    nathan v

    February 25, 2016 at 8:22pm

    thank you sir
    You are rock!!!!
    good simple example

  15. Permalink  ⋅ Reply

    Son Lam

    March 2, 2017 at 7:26pm

    Hello,

    I just downloaded jetty-distribution-9.4.2.v20170220. and got following compilation errors:

    Would you know they have done any breaking change?

    Exception in thread “main” java.lang.Error: Unresolved compilation problems:
    The method start() is undefined for the type WebSocketClient
    The type org.eclipse.jetty.websocket.api.Session cannot be resolved. It is indirectly referenced from required .class files
    The method connect(Object, URI, ClientUpgradeRequest) from the type WebSocketClient refers to the missing type Session
    The method awaitClose(int, TimeUnit) is undefined for the type IgnitionAdapter
    The type org.eclipse.jetty.util.component.ContainerLifeCycle cannot be resolved. It is indirectly referenced from required .class files
    The type org.eclipse.jetty.websocket.common.scopes.WebSocketContainerScope cannot be resolved. It is indirectly referenced from required .class files
    The method stop() is undefined for the type WebSocketClient

    at com.tesla.hermes.ignitionadapter.IgnitionAdapter.main(IgnitionAdapter.java:27)

Leave a Reply

Your email will not be published. Name and Email fields are required.