public WebSocket<JsonNode> socket() {
        final Http.Session session = session();
        final User currentUser = Application.getLocalUser(session());
        return new WebSocket<JsonNode>() {
            @Override
            public void onReady(In<JsonNode> in, Out<JsonNode> out) {
                try {
                    User u = Application.getLocalUser(session);
                    //Logger.debug("User " + u.id + " connected");
                    // Add the new user to the data structures
                    boolean alreadyOnline = onlineUsers.containsValue(u);
                    onlineUsers.put(out, u);
                    /*try (Jedis j = jedisPool.getResource()) {
                        j.sadd("online_users", Long.toString(u.id));
                    }*/
                    // Notify logged users about the new player
                    if (!alreadyOnline) {
                        ObjectMapper mapper = new ObjectMapper();
                        ObjectNode notification = JsonNodeFactory.instance.objectNode();
                        notification.put("action", "newuser");
                        notification.put("newuser", mapper.writeValueAsString(currentUser));
                        broadcastMessage(notification, new HashSet<User>() {{ add(u); }});
                    }
                } catch (RuntimeException e) {
                    //Logger.debug("Unknown user connected");
                } catch (JsonProcessingException e) {
                    Logger.error(e.getMessage(), e);
                }
                in.onMessage((data) -> {
                    Logger.debug(currentUser.id + " - " + data.toString());
                    String action = data.findPath("action").textValue();
                    switch (action) {
                        // TODO: add error handling
                        case "newgame":
                            onNewGameResponse(data, currentUser);
                            break;
                        case "ready":
                            onUserReady(data, currentUser);
                            break;
                        case "setrowboat":
                            onSetShip(data, currentUser, new Rowboat());
                            break;
                        case "setdestructor":
                            onSetShip(data, currentUser, new Destructor());
                            break;
                        case "setflattop":
                            onSetShip(data, currentUser, new Flattop());
                            break;
                        case "shoot":
                            onShoot(data, currentUser);
                            break;
                        case "userleaves":
                            onUserLeaves(data, currentUser);
                            break;
                        case "getOnlineUsers":
                            onGetOnlineUsers(data, currentUser);
                            break;
                        default:
                    }
                });
                in.onClose(() -> {
                    User u = onlineUsers.get(out);
                    if (u != null) {
                        //Logger.debug("User " + u.id + " disconnected");
                        // Remove user from the data structures
                        onlineUsers.remove(out);
                        // Wait for 100 ms to see if the user connects through another websocket
                        //Thread.sleep(100);
                        boolean stillOnline = onlineUsers.containsValue(u);
                        /*try (Jedis j = jedisPool.getResource()) {
                            j.srem("online_users", Long.toString(u.id));
                        }*/
                        // Notify logged users about the leaving player
                        if (!stillOnline) {
                            try {
                                ObjectMapper mapper = new ObjectMapper();
                                ObjectNode notification = JsonNodeFactory.instance.objectNode();
                                notification.put("action", "userleaves");
                                notification.put("leavinguser", mapper.writeValueAsString(currentUser));
                                broadcastMessage(notification, new HashSet<User>() {{ add(u); }});
                            } catch (JsonProcessingException e) {
                                Logger.error(e.getMessage(), e);
                            }
                        }
                    } else {
                        //Logger.debug("Unknown user disconnected");
                    }
                });
            }
        };
    }
public WebSocket<JsonNode> socket() {
        final Http.Session session = session();
        final User currentUser = Application.getLocalUser(session());
        return new WebSocket<JsonNode>() {
            @Override
            public void onReady(In<JsonNode> in, Out<JsonNode> out) {
                try {
                    User u = Application.getLocalUser(session);
                   
                   
                    boolean alreadyOnline = onlineUsers.containsValue(u);
                    onlineUsers.put(out, u);
                   
                   
                    if (!alreadyOnline) {
                        ObjectMapper mapper = new ObjectMapper();
                        ObjectNode notification = JsonNodeFactory.instance.objectNode();
                        notification.put("action", "newuser");
                        notification.put("newuser", mapper.writeValueAsString(currentUser));
                        broadcastMessage(notification, new HashSet<User>() {{ add(u); }});
                    }
                } catch (RuntimeException e) {
                   
                } catch (JsonProcessingException e) {
                    Logger.error(e.getMessage(), e);
                }
                in.onMessage((data) -> {
                    Logger.debug(currentUser.id + " - " + data.toString());
                    String action = data.findPath("action").textValue();
                    switch (action) {
                       
                        case "newgame":
                            onNewGameResponse(data, currentUser);
                            break;
                        case "ready":
                            onUserReady(data, currentUser);
                            break;
                        case "setrowboat":
                            onSetShip(data, currentUser, new Rowboat());
                            break;
                        case "setdestructor":
                            onSetShip(data, currentUser, new Destructor());
                            break;
                        case "setflattop":
                            onSetShip(data, currentUser, new Flattop());
                            break;
                        case "shoot":
                            onShoot(data, currentUser);
                            break;
                        case "userleaves":
                            onUserLeaves(data, currentUser);
                            break;
                        case "getOnlineUsers":
                            onGetOnlineUsers(data, currentUser);
                            break;
                        default:
                    }
                });
                in.onClose(() -> {
                    User u = onlineUsers.get(out);
                    if (u != null) {
                       
                       
                        onlineUsers.remove(out);
                       
                       
                        boolean stillOnline = onlineUsers.containsValue(u);
                       
                       
                        if (!stillOnline) {
                            try {
                                ObjectMapper mapper = new ObjectMapper();
                                ObjectNode notification = JsonNodeFactory.instance.objectNode();
                                notification.put("action", "userleaves");
                                notification.put("leavinguser", mapper.writeValueAsString(currentUser));
                                broadcastMessage(notification, new HashSet<User>() {{ add(u); }});
                            } catch (JsonProcessingException e) {
                                Logger.error(e.getMessage(), e);
                            }
                        }
                    } else {
                       
                    }
                });
            }
        };
    }
public websocket<jsonnode> socket() { final http.session session = session(); final user currentuser = application.getlocaluser(session()); return new websocket<jsonnode>() { @override public void onready(in<jsonnode> in, out<jsonnode> out) { try { user u = application.getlocaluser(session); boolean alreadyonline = onlineusers.containsvalue(u); onlineusers.put(out, u); if (!alreadyonline) { objectmapper mapper = new objectmapper(); objectnode notification = jsonnodefactory.instance.objectnode(); notification.put("action", "newuser"); notification.put("newuser", mapper.writevalueasstring(currentuser)); broadcastmessage(notification, new hashset<user>() {{ add(u); }}); } } catch (runtimeexception e) { } catch (jsonprocessingexception e) { logger.error(e.getmessage(), e); } in.onmessage((data) -> { logger.debug(currentuser.id + " - " + data.tostring()); string action = data.findpath("action").textvalue(); switch (action) { case "newgame": onnewgameresponse(data, currentuser); break; case "ready": onuserready(data, currentuser); break; case "setrowboat": onsetship(data, currentuser, new rowboat()); break; case "setdestructor": onsetship(data, currentuser, new destructor()); break; case "setflattop": onsetship(data, currentuser, new flattop()); break; case "shoot": onshoot(data, currentuser); break; case "userleaves": onuserleaves(data, currentuser); break; case "getonlineusers": ongetonlineusers(data, currentuser); break; default: } }); in.onclose(() -> { user u = onlineusers.get(out); if (u != null) { onlineusers.remove(out); boolean stillonline = onlineusers.containsvalue(u); if (!stillonline) { try { objectmapper mapper = new objectmapper(); objectnode notification = jsonnodefactory.instance.objectnode(); notification.put("action", "userleaves"); notification.put("leavinguser", mapper.writevalueasstring(currentuser)); broadcastmessage(notification, new hashset<user>() {{ add(u); }}); } catch (jsonprocessingexception e) { logger.error(e.getmessage(), e); } } } else { } }); } }; }