@Override protected void onSocketClosed(final WebSocket socket) throws IOException { final QueueSession session = sessionProvider.createOrGetSession(socket.getHttpSession(), socket.getSocketID()); final LocalContext localSessionContext = LocalContext.get(session); final QueueSession cometSession = localSessionContext.getAttribute(QueueSession.class, WEBSOCKET_SESSION_ALIAS); service.getBus().getQueue(cometSession).setDirectSocketChannel(null); }
@Override protected void onReceivedFrame(final WebSocket socket) throws IOException { final Frame frame = socket.readFrame(); switch (frame.getType()) { case Ping: socket.writeFrame(new PongFrame()); break; case Binary: socket.writeFrame(TextFrame.from("Binary Frames Not Supported!")); break; default: if (frame.getType() != FrameType.Text) { return; } } final String text = ((TextFrame) frame).getText(); final QueueSession session = sessionProvider.createOrGetSession(socket.getHttpSession(), socket.getSocketID()); if (text.length() == 0) return; @SuppressWarnings("unchecked") final EJObject val = JSONDecoder.decode(text).isObject(); final LocalContext localSessionContext = LocalContext.get(session); QueueSession cometSession = localSessionContext.getAttribute(QueueSession.class, WEBSOCKET_SESSION_ALIAS); // this is not an active channel. if (cometSession == null) { final String commandType = val.get(MessageParts.CommandType.name()).isString().stringValue(); // this client apparently wants to connect. if (BusCommands.ConnectToQueue.name().equals(commandType)) { final String sessionKey = val.get(MessageParts.ConnectionSessionKey.name()).isString().stringValue(); // has this client already attempted a connection, and is in a wait verify state if (sessionKey != null && (cometSession = service.getBus().getSessionBySessionId(sessionKey)) != null) { final LocalContext localCometSession = LocalContext.get(cometSession); if (localCometSession.hasAttribute(WebSocketServerHandler.SESSION_ATTR_WS_STATUS) && WebSocketServerHandler.WEBSOCKET_ACTIVE.equals( localCometSession.getAttribute( String.class, WebSocketServerHandler.SESSION_ATTR_WS_STATUS))) { // set the session queue into direct channel mode. service .getBus() .getQueue(cometSession) .setDirectSocketChannel(new SimpleEventChannelWrapped(socket)); localSessionContext.setAttribute(WEBSOCKET_SESSION_ALIAS, cometSession); cometSession.removeAttribute(WebSocketServerHandler.SESSION_ATTR_WS_STATUS); return; } // check the activation key matches. final EJString activationKey = val.get(MessageParts.WebSocketToken.name()).isString(); if (activationKey == null || !WebSocketTokenManager.verifyOneTimeToken( cometSession, activationKey.stringValue())) { // nope. go away! sendMessage( new SimpleEventChannelWrapped(socket), getFailedNegotiation("bad negotiation key")); } else { // the key matches. now we send the reverse challenge to prove this client is actually // already talking to the bus over the COMET channel. final String reverseToken = WebSocketTokenManager.getNewOneTimeToken(cometSession); localCometSession.setAttribute( WebSocketServerHandler.SESSION_ATTR_WS_STATUS, WebSocketServerHandler.WEBSOCKET_AWAIT_ACTIVATION); // send the challenge. sendMessage(new SimpleEventChannelWrapped(socket), getReverseChallenge(reverseToken)); return; } sendMessage(new SimpleEventChannelWrapped(socket), getSuccessfulNegotiation()); } else { sendMessage( new SimpleEventChannelWrapped(socket), getFailedNegotiation("bad session id")); } } else { sendMessage(new SimpleEventChannelWrapped(socket), getFailedNegotiation("bad command")); } } else { // this is an active session. send the message.; final Message msg = MessageFactory.createCommandMessage(cometSession, text); msg.setResource(HttpServletRequest.class.getName(), socket.getServletRequest()); service.store(msg); } }