Translate

Saturday, August 15, 2015

Java - Using web socket for push notifications

I was working on a small web application that had a long running server process and I thought it would be good to send a progress notification back to the user. The client is identified on the server by their session.

The controller:

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import java.util.Map.Entry;
import javax.servlet.http.HttpSession;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;


@ServerEndpoint(value = "/mainwebsock", 
        configurator = GetHttpSessionConfigurator.class)
public class MainControllerWebSocket {
 private static Map mSessions = new HashMap();
 
 @OnMessage
 public void onMessage(String message, Session session) throws IOException,
   InterruptedException {
  System.out.println("User input: " + message);
  session.getBasicRemote().sendText("Hello world Mr. " + message);
  // Sending message to client each 1 second
  for (int i = 0; i <= 6; i++) {
   session.getBasicRemote().sendText(i + " Message from server");
   Thread.sleep(1000);

  }
 }
 
 public static void sendMessage(String message, String strSessionID){
  try {
   @SuppressWarnings("resource")
   Session mySes = mSessions.get(strSessionID);
   if (mySes != null && mySes.isOpen()) mySes.getBasicRemote().sendText(message);
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

    @OnOpen
    public void open(Session session, EndpointConfig config) {
     HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        mSessions.put(httpSession.getId(), session);
        System.out.println("Client connected on session: " + httpSession.getId());
    }

 @SuppressWarnings("rawtypes")
 @OnClose
 public void onClose(Session session) {
  for (Iterator iter = mSessions.entrySet().iterator(); iter.hasNext();) {
     @SuppressWarnings("unchecked")
   Map.Entry  e = (Entry) iter.next();
     if (e.getValue().getId() == session.getId() ) {
      iter.remove();
     }}
  System.out.println("Connection closed");
 }
}


The session configurator:

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;

public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator
{
    @Override
    public void modifyHandshake(ServerEndpointConfig config, 
                                HandshakeRequest request, 
                                HandshakeResponse response)
    {
        HttpSession httpSession = (HttpSession)request.getHttpSession();
        config.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }
}

The JavaScript:

var webSocket = null;

function connect() {
 var wsURI = 'ws://' + window.location.host + '/INagresso/mainwebsock';
 console.log("Connecting");
 webSocket = new WebSocket(wsURI);
 
 webSocket.onerror = function(event) {
  displayMessage(event.data);
 };
 
 webSocket.onopen = function(event) {
  displayMessage("Connection open.");
 };
 
 webSocket.onmessage = function(event) {
  displayMessage(event.data);
 };
 
}


function displayMessage(data) {
document.getElementById('main_content').innerHTML += '
' + data; } function disconnect() { if (webSocket !== null) { webSocket.close(); webSocket = null; } displayMessage("WebSocket closed."); } //Button click handler function createADAcccount(){ if (webSocket == null) {connect();} $('div#main_content').empty(); $('li#value_input').html('<h1>Create AD Accounts</h1>'); $("div#main_content").load('${pageContext.request.contextPath}/testCreateAccountsAD'); }

In any server process when we want to send a message to the web client we call:

//strMessage is the message we want to send 
//and mySession.getId() is the HttpSession Id
MainControllerWebSocket.sendMessage(strMessage, mySession.getId());
Git Project

No comments:

Post a Comment

Thank you for commenting!