CODEXE

WebSocket

I will use an example which is to get the comments update in real time to explain the process.

1. Create a WebSocket endpoint. This is the port that client can make communications with server.


@ApplicationScoped
@ServerEndpoint(value="/realtime/comments/{userid}")
public class RealTimeCommentWebSocketServer {
	private RealTimeCommentSessionHandler sessionHandler = new RealTimeCommentSessionHandler();
	private Gson gson = new Gson();
	@OnOpen
	public void open(Session session,@PathParam("userid") String userid) {
		int userId = Integer.valueOf(userid);
		sessionHandler.addSession(userId, session);
		//When user open the connect, we generally return the initial status of comment updates
		sessionHandler.sendToSession(userId,false);
	}
	@OnClose
	public void close(Session session) {
		sessionHandler.removeSession(session);
	}
	@OnError
	public void onError(Throwable error) {
		error.printStackTrace();
	}
	@OnMessage
	public void handleMessage(String message, Session session) {
		//get the message from client here
	}
	
}
            	

2. Create session handler to control the actual communication


@ApplicationScoped
public class RealTimeCommentSessionHandler {
	//hashtable is synchronized
	//user id + session list. one use account may login different client. easy to update to all "same users"
	private static Hashtable<Integer, List<Session>> userSession = new Hashtable<Integer,List<Session>>();
	//session + user id
	private static Hashtable<Session, Integer> sessionUser = new Hashtable<Session, Integer>();
	
	public synchronized void addSession(Integer userId, Session session) {
	//update two hash tables
		sessionUser.put(session, userId);
		List<Session> list = userSession.getOrDefault(userId, new LinkedList<Session>());
		list.add(session);
		userSession.put(userId, list);
	}
	public synchronized void removeSession(Session session) {
	//remove from both hash tables
		int userId  =sessionUser.get(session);
		sessionUser.remove(session);
		
		List<Session> list = userSession.getOrDefault(userId, new LinkedList<Session>());
		list.remove(session);
		userSession.put(userId, list);
	}
	public synchronized static void sendToAllSessions(List<Integer> userIds, boolean isOnline) {
		//get update from DB and send to all realted users.
		//once user read the unread comments, they will be deleted from DB. This should be another topic...
		OfferCommentUpdateManager commentUpdateManager = new OfferCommentUpdateManager();
		for(int userId : userIds) {
			Long res = isOnline?commentUpdateManager.getUnreadOfferCommentNum(userId):commentUpdateManager.getUnreadOfferCommentNumWS(userId);
			List<Session> sessions = userSession.get(userId);
			if(sessions!=null) {
				for(Session session : sessions) {
					if(session !=null) {
						try {
						//send the number of unread comments
							session.getBasicRemote().sendText(String.valueOf(res));
						} catch (IOException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}
	}
	public synchronized static void sendToSession(int userId, boolean isOnline) {
	//send to a specific user
		OfferCommentUpdateManager commentUpdateManager = new OfferCommentUpdateManager();
		Long res = isOnline?commentUpdateManager.getUnreadOfferCommentNum(userId):commentUpdateManager.getUnreadOfferCommentNumWS(userId);
		List<Session> sessions = userSession.get(userId);
		if(sessions!=null) {
			for(Session session : sessions) {
				if(session!=null) {
					try {
						session.getBasicRemote().sendText(String.valueOf(res));
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

}
            	

3. Open the WebSocket in client side and listen on it


function connectFollowWS(){
	var wsFollowUri = getRootUri() + "/realtime/comments/"+userId;//the url contains the user id
		websocketComment = new WebSocket(wsFollowUri);
	    websocketComment.onmessage = onCommentMessage;
}
function getRootUri() {
    return "ws://" + (document.location.hostname == "" ? "localhost" : document.location.hostname) + ":" +
            (document.location.hostname == "" ? "8080" : ""/*document.location.port*/);
   /* (document.location.port == "" ? "8080" : ""document.location.port);*/
}

function onCommentMessage(evt) {
   
    var data = evt.data;
    if(data==='0'){
    	//no comment and hide the notification symbol
    	$(".realtime-comment").hide();
    	
    	$(".update-remind").hide();
    }
    else{
    	//Show the number of new comment
    	$(".realtime-comment").find(".commentnum").html(data);
    	$(".realtime-comment").show();
    	$(".update-remind").css('display','inline-block');
    }
}
            	

This page can help a lot.