November 19, 2017

Java EE 7 Simple WebSocket Example

One of the new technologies in Java EE 7 is WebSockets. A killer use case for web sockets is when a client need push notifications from the server. Previously such a client needed to constantly ask the server if there were any updates, which was ineffective and consumed a lot of server cpu. So lets implement a simple chat application that uses web sockets.

First the server. The whole layout or architecture behind web sockets reminds us very much as with jax-rs annotations. We start with a @ServerEndpoint class annotation, just like rest @Path.

Then you have only one mandatory method @OnMessage public void onMessage(String message, Session session). The method input parameters can be different, please read the javadoc.

Then you have 3 optional methods documented here. @OnOpen, @OnClose and @OnError

I will implement all 4 methods. I will also remember all sessions and will use CDI annotation @ApplicationScoped for that, but for it to work, we need to put the data in a separate POJO and annotate that also with @ApplicationScoped and let CDI handle the lifecycle via @Inject.


import java.util.logging.Level;
import java.util.logging.Logger;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

public class ChatWebSocketServer {

    private final Logger log = Logger.getLogger(ChatWebSocketServer.class.getName());
    @Inject ChatSessions sessions;

    public void open(Session session) {
        sessions.getSessions().put(session.getId(), session);"OPEN session " + session.getId());"size " + sessions.getSessions().size());

    public void close(Session session) {
        sessions.getSessions().remove(session.getId());"CLOSE session " + session.getId());"size " + sessions.getSessions().size());

    public void onError(Throwable error) {
        log.log(Level.SEVERE, "onError", error);

    public void handleMessage(final String message, Session session) {"size " + sessions.getSessions().size());
        sessions.getSessions().forEach((key, value) -> {
            try {
      "SEND session " + value.getId() + ", message " + message);
            } catch (Exception e) {
                log.log(Level.SEVERE, "Failed to send text", e);


import java.util.HashMap;
import java.util.Map;
import javax.enterprise.context.ApplicationScoped;
import javax.websocket.Session;

public class ChatSessions {
    private final Map<String, Session> sessions = new HashMap<>();

    public Map<String, Session> getSessions() {
        return sessions;

Now to the client. It is made up of a web page and javascript.

<!DOCTYPE html>
        <title>Web Socket Demo</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="websocket.js"></script>
            <form id="chatForm">
                Message: <input type="text" id="message" />
                <input type="button" value="Send" onclick="formSubmit()" />
        <div id="messages">

var socket = new WebSocket("ws://localhost:8080/example-javaee7/chat");
socket.onmessage = onMessage;

function onMessage(event) {
    var message =;
    appendHtml("<--- Server : " + message);

function formSubmit() {
    var form = document.getElementById("chatForm");
    var message = form.elements["message"].value;
    appendHtml("---> You : " + message);

function appendHtml(message) {
    var div = document.getElementById("messages")
    div.innerHTML += "

" + message + "

"; }

No comments: