private void handleSendFailureWithEncode(Throwable t) throws IOException, EncodeException { // First, unwrap any execution exception if (t instanceof ExecutionException) { t = t.getCause(); } // Close the session wsSession.doClose(new CloseReason(CloseCodes.GOING_AWAY, t.getMessage()), new CloseReason(CloseCodes.CLOSED_ABNORMALLY, t.getMessage())); // Rethrow the exception if (t instanceof EncodeException) { throw (EncodeException) t; } if (t instanceof IOException) { throw (IOException) t; } throw new IOException(t); }
/** * Called when a close message is received. Should only ever happen once. * Also called after a protocol error when the ProtocolHandler needs to * force the closing of the connection. */ public void onClose(CloseReason closeReason) { synchronized (stateLock) { if (state != State.CLOSED) { try { wsRemoteEndpoint.setBatchingAllowed(false); } catch (IOException e) { log.warn(sm.getString("wsSession.flushFailOnClose"), e); fireEndpointOnError(e); } if (state == State.OPEN) { state = State.OUTPUT_CLOSED; sendCloseMessage(closeReason); fireEndpointOnClose(closeReason); } state = State.CLOSED; // Close the socket wsRemoteEndpoint.close(); } } }
@SuppressWarnings("unchecked") private void sendMessageBinary(ByteBuffer msg, boolean last) throws WsIOException { if (binaryMsgHandler instanceof WrappedMessageHandler) { long maxMessageSize = ((WrappedMessageHandler) binaryMsgHandler).getMaxMessageSize(); if (maxMessageSize > -1 && msg.remaining() > maxMessageSize) { throw new WsIOException(new CloseReason(CloseCodes.TOO_BIG, sm.getString("wsFrame.messageTooBig", Long.valueOf(msg.remaining()), Long.valueOf(maxMessageSize)))); } } try { if (binaryMsgHandler instanceof MessageHandler.Partial<?>) { ((MessageHandler.Partial<ByteBuffer>) binaryMsgHandler).onMessage(msg, last); } else { // Caller ensures last == true if this branch is used ((MessageHandler.Whole<ByteBuffer>) binaryMsgHandler).onMessage(msg); } } catch(Throwable t) { handleThrowableOnSend(t); } }
@Override public final void onClose(Session session, CloseReason closeReason) { if (methodMapping.getOnClose() != null) { try { methodMapping.getOnClose().invoke(pojo, methodMapping.getOnCloseArgs(pathParameters, session, closeReason)); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); log.error(sm.getString("pojoEndpointBase.onCloseFail", pojo.getClass().getName()), t); } } // Trigger the destroy method for any associated decoders Set<MessageHandler> messageHandlers = session.getMessageHandlers(); for (MessageHandler messageHandler : messageHandlers) { if (messageHandler instanceof PojoMessageHandlerWholeBase<?>) { ((PojoMessageHandlerWholeBase<?>) messageHandler).onClose(); } } }
@SuppressWarnings("unchecked") private void sendMessageText(boolean last) throws WsIOException { if (textMsgHandler instanceof WrappedMessageHandler) { long maxMessageSize = ((WrappedMessageHandler) textMsgHandler).getMaxMessageSize(); if (maxMessageSize > -1 && messageBufferText.remaining() > maxMessageSize) { throw new WsIOException(new CloseReason(CloseCodes.TOO_BIG, sm.getString("wsFrame.messageTooBig", Long.valueOf(messageBufferText.remaining()), Long.valueOf(maxMessageSize)))); } } try { if (textMsgHandler instanceof MessageHandler.Partial<?>) { ((MessageHandler.Partial<String>) textMsgHandler).onMessage(messageBufferText.toString(), last); } else { // Caller ensures last == true if this branch is used ((MessageHandler.Whole<String>) textMsgHandler).onMessage(messageBufferText.toString()); } } catch (Throwable t) { handleThrowableOnSend(t); } finally { messageBufferText.clear(); } }
/** * Cleans up the resources still in use by WebSocket sessions created from * this container. This includes closing sessions and cancelling * {@link Future}s associated with blocking read/writes. */ public void destroy() { CloseReason cr = new CloseReason( CloseCodes.GOING_AWAY, sm.getString("wsWebSocketContainer.shutdown")); for (WsSession session : sessions.keySet()) { try { session.close(cr); } catch (IOException ioe) { log.debug(sm.getString( "wsWebSocketContainer.sessionCloseFail", session.getId()), ioe); } } // Only unregister with AsyncChannelGroupUtil if this instance // registered with it if (asynchronousChannelGroup != null) { synchronized (asynchronousChannelGroupLock) { if (asynchronousChannelGroup != null) { AsyncChannelGroupUtil.unregister(); asynchronousChannelGroup = null; } } } }
/** * @return * Returns an object of Reconnect Handler * Responsible for reconnecting to the server when connection loses * Handle any networking issues as well */ private ReconnectHandler getReconnecHandler() { ClientManager.ReconnectHandler reconnectHandler = new ClientManager.ReconnectHandler() { @Override public boolean onDisconnect(CloseReason closeReason) { // If we close the session no need to reconnect if (WebSocketClient.this.isInterrupted || closeReason.getCloseCode() == CloseReason.CloseCodes.NORMAL_CLOSURE) { return false; } reconnect("Disconnected.... Trying to reconnect .... " + closeReason); return true; } @Override public boolean onConnectFailure(Exception exception) { if (!WebSocketClient.this.isInterrupted) { reconnect("Connection Failure... Attempting to reconnect ..." + exception.toString()); return true; } return false; } }; return reconnectHandler; }
/** * When user leaves the activity. */ @OnClose public void unregisterUser(Session websocket, CloseReason reason) { Long toolContentID = Long .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_CONTENT_ID).get(0)); websockets.get(toolContentID).remove(websocket); if (log.isDebugEnabled()) { // If there was something wrong with the connection, put it into logs. log.debug("User " + websocket.getUserPrincipal().getName() + " left Dokumaran with Tool Content ID: " + toolContentID + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
/** * When user leaves the activity. */ @OnClose public void unregisterUser(Session websocket, CloseReason reason) { Long toolSessionId = Long .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); websockets.get(toolSessionId).remove(websocket); if (log.isDebugEnabled()) { // If there was something wrong with the connection, put it into logs. log.debug("User " + websocket.getUserPrincipal().getName() + " left Leader Selection with Tool Session ID: " + toolSessionId + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
/** * If there was something wrong with the connection, put it into logs. */ @OnClose public void unregisterUser(Session session, CloseReason reason) { Long lessonId = Long.valueOf(session.getRequestParameterMap().get(AttributeNames.PARAM_LESSON_ID).get(0)); Set<Websocket> lessonWebsockets = PresenceWebsocketServer.websockets.get(lessonId); Iterator<Websocket> websocketIterator = lessonWebsockets.iterator(); while (websocketIterator.hasNext()) { Websocket websocket = websocketIterator.next(); if (websocket.session.equals(session)) { websocketIterator.remove(); break; } } if (PresenceWebsocketServer.log.isDebugEnabled()) { PresenceWebsocketServer.log.debug( "User " + session.getUserPrincipal().getName() + " left Presence Chat with lessonId: " + lessonId + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
@OnClose public void unregisterUser(Session websocket, CloseReason reason) throws JSONException, IOException { String login = websocket.getUserPrincipal().getName(); if (login == null) { return; } Integer organisationId = Integer .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_ORGANISATION_ID).get(0)); KumaliveDTO kumalive = kumalives.get(organisationId); if (kumalive == null) { return; } KumaliveUser user = kumalive.learners.remove(login); if (user != null) { Integer userId = user.userDTO.getUserID(); if (kumalive.raisedHand != null) { kumalive.raisedHand.remove(userId); } if (userId.equals(kumalive.speaker)) { kumalive.speaker = null; } } sendRefresh(kumalive); }
/** * Removes Learner websocket from the collection. */ @OnClose public void unregisterUser(Session session, CloseReason reason) { String login = session.getUserPrincipal().getName(); if (login == null) { return; } Long lessonId = Long.valueOf(session.getRequestParameterMap().get(AttributeNames.PARAM_LESSON_ID).get(0)); Map<String, Session> lessonWebsockets = CommandWebsocketServer.websockets.get(lessonId); if (lessonWebsockets == null) { return; } lessonWebsockets.remove(login); }
/** * When user leaves the activity. */ @OnClose public void unregisterUser(Session session, CloseReason reason) { Long toolSessionId = Long .valueOf(session.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); Set<Websocket> sessionWebsockets = LearningWebsocketServer.websockets.get(toolSessionId); Iterator<Websocket> websocketIterator = sessionWebsockets.iterator(); while (websocketIterator.hasNext()) { Websocket websocket = websocketIterator.next(); if (websocket.session.equals(session)) { websocketIterator.remove(); break; } } if (LearningWebsocketServer.log.isDebugEnabled()) { LearningWebsocketServer.log.debug( "User " + session.getUserPrincipal().getName() + " left Chat with toolSessionId: " + toolSessionId + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
/** * When user leaves the activity. */ @OnClose public void unregisterUser(Session websocket, CloseReason reason) { Long toolSessionId = Long .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); LearningWebsocketServer.websockets.get(toolSessionId).remove(websocket); if (LearningWebsocketServer.log.isDebugEnabled()) { // If there was something wrong with the connection, put it into logs. LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + " left Scratchie with Tool Session ID: " + toolSessionId + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
/** * When user leaves the activity. */ @OnClose public void unregisterUser(Session websocket, CloseReason reason) { Long toolSessionId = Long .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_TOOL_SESSION_ID).get(0)); LearningWebsocketServer.websockets.get(toolSessionId).remove(websocket); if (LearningWebsocketServer.log.isDebugEnabled()) { // If there was something wrong with the connection, put it into logs. LearningWebsocketServer.log.debug("User " + websocket.getUserPrincipal().getName() + " left Scribe with Tool Session ID: " + toolSessionId + (!(reason.getCloseCode().equals(CloseCodes.GOING_AWAY) || reason.getCloseCode().equals(CloseCodes.NORMAL_CLOSURE)) ? ". Abnormal close. Code: " + reason.getCloseCode() + ". Reason: " + reason.getReasonPhrase() : "")); } }
/** * Close Websocket connection Connection * @param session */ private void closeWebSocketConnection(final Session session ){ try { Thread.sleep(3000); } catch (InterruptedException e1) { } if (session != null && session.isOpen()) { try { CloseReason closeReason = new CloseReason( CloseCodes.NORMAL_CLOSURE, "Session Closed"); session.close(closeReason); } catch (IOException e) { e.printStackTrace(); } } }
/** * * Close websocket client connection. * @param session */ public void closeWebSocketConnection(Session session){ try { Thread.sleep(DELAY); } catch (InterruptedException e1) { } if (session != null && session.isOpen()) { try { CloseReason closeReason = new CloseReason(CloseCodes.NORMAL_CLOSURE,"Closed"); session.close(closeReason); logger.info("Session closed"); } catch (IOException e) { logger.error("Fail to close connection ",e); } } }
@Override public void onClose(Session session, CloseReason closeReason) { Room room = getRoom(false); if (room != null) { room.invokeAndWait(new Runnable() { @Override public void run() { try { // Player can be null if it couldn't enter the room if (player != null) { // Remove this player from the room. player.removeFromRoom(); // Set player to null to prevent NPEs when onMessage events // are processed (from other threads) after onClose has been // called from different thread which closed the Websocket session. player = null; } } catch (RuntimeException ex) { log.error("Unexpected exception: " + ex.toString(), ex); } } }); } }
@PreDestroy public void shutdown() { scheduledExecutorService.shutdown(); clientsSessions.forEach(session -> { try { if (!session.isOpen()) { return; } session.close(new CloseReason(CloseCodes.SERVICE_RESTART, "Shutting down")); } catch (Exception e) { LOGGER.error("Error while closing session", e); } }); }
private void close(CloseReason cr) { /* * Any call to this method is a result of a problem reading from the * client. At this point that state of the connection is unknown. * Attempt to send a close frame to the client and then close the socket * immediately. There is no point in waiting for a close frame from the * client because there is no guarantee that we can recover from * whatever messed up state the client put the connection into. */ wsSession.onClose(cr); }
public void close(CloseReason closeReason) throws IOException { HttpSession httpSession = (HttpSession) session.getUserProperties().get(HttpSession.class.getName()); httpSession.removeAttribute(WObject.class.getName()); httpSession.removeAttribute(PorterOfFun.class.getName()); httpSession.removeAttribute(WebSocket.class.getName()); if (closeReason != null) { session.close(closeReason); } else { session.close(); } }
/** * WebSocket 1.0. Section 2.1.5. * Need internal close method as spec requires that the local endpoint * receives a 1006 on timeout. */ public void doClose(CloseReason closeReasonMessage, CloseReason closeReasonLocal) { // Double-checked locking. OK because state is volatile if (state != State.OPEN) { return; } synchronized (stateLock) { if (state != State.OPEN) { return; } if (log.isDebugEnabled()) { log.debug(sm.getString("wsSession.doClose", id)); } try { wsRemoteEndpoint.setBatchingAllowed(false); } catch (IOException e) { log.warn(sm.getString("wsSession.flushFailOnClose"), e); fireEndpointOnError(e); } state = State.OUTPUT_CLOSED; sendCloseMessage(closeReasonMessage); fireEndpointOnClose(closeReasonLocal); } IOException ioe = new IOException(sm.getString("wsSession.messageFailed")); SendResult sr = new SendResult(ioe); for (FutureToSendHandler f2sh : futures.keySet()) { f2sh.onResult(sr); } }
private void fireEndpointOnClose(CloseReason closeReason) { // Fire the onClose event Throwable throwable = null; InstanceManager instanceManager = webSocketContainer.getInstanceManager(); Thread t = Thread.currentThread(); ClassLoader cl = t.getContextClassLoader(); t.setContextClassLoader(applicationClassLoader); try { localEndpoint.onClose(this, closeReason); } catch (Throwable t1) { ExceptionUtils.handleThrowable(t1); throwable = t1; } finally { if (instanceManager != null) { try { instanceManager.destroyInstance(localEndpoint); } catch (Throwable t2) { ExceptionUtils.handleThrowable(t2); if (throwable == null) { throwable = t2; } } } t.setContextClassLoader(cl); } if (throwable != null) { fireEndpointOnError(throwable); } }
private void sendCloseMessage(CloseReason closeReason) { // 125 is maximum size for the payload of a control message ByteBuffer msg = ByteBuffer.allocate(125); CloseCode closeCode = closeReason.getCloseCode(); // CLOSED_ABNORMALLY should not be put on the wire if (closeCode == CloseCodes.CLOSED_ABNORMALLY) { // PROTOCOL_ERROR is probably better than GOING_AWAY here msg.putShort((short) CloseCodes.PROTOCOL_ERROR.getCode()); } else { msg.putShort((short) closeCode.getCode()); } String reason = closeReason.getReasonPhrase(); if (reason != null && reason.length() > 0) { appendCloseReasonWithTruncation(msg, reason); } msg.flip(); try { wsRemoteEndpoint.startMessageBlock(Constants.OPCODE_CLOSE, msg, true); } catch (IOException ioe) { handleCloseException(ioe, closeCode); } catch (WritePendingException wpe) { handleCloseException(wpe, closeCode); } finally { webSocketContainer.unregisterSession(localEndpoint, this); } }
protected void checkExpiration() { long timeout = maxIdleTimeout; if (timeout < 1) { return; } if (System.currentTimeMillis() - lastActive > timeout) { String msg = sm.getString("wsSession.timeout"); doClose(new CloseReason(CloseCodes.GOING_AWAY, msg), new CloseReason(CloseCodes.CLOSED_ABNORMALLY, msg)); } }
@SuppressWarnings("unchecked") private void sendMessageText(boolean last) throws WsIOException { if (textMsgHandler instanceof WrappedMessageHandler) { long maxMessageSize = ((WrappedMessageHandler) textMsgHandler).getMaxMessageSize(); if (maxMessageSize > -1 && messageBufferText.remaining() > maxMessageSize) { throw new WsIOException(new CloseReason(CloseCodes.TOO_BIG, sm.getString("wsFrame.messageTooBig", Long.valueOf(messageBufferText.remaining()), Long.valueOf(maxMessageSize)))); } } try { if (textMsgHandler instanceof MessageHandler.Partial<?>) { ((MessageHandler.Partial<String>) textMsgHandler).onMessage( messageBufferText.toString(), last); } else { // Caller ensures last == true if this branch is used ((MessageHandler.Whole<String>) textMsgHandler).onMessage( messageBufferText.toString()); } } catch (Throwable t) { handleThrowableOnSend(t); } finally { messageBufferText.clear(); } }
private void handleThrowableOnSend(Throwable t) throws WsIOException { ExceptionUtils.handleThrowable(t); wsSession.getLocal().onError(wsSession, t); CloseReason cr = new CloseReason(CloseCodes.CLOSED_ABNORMALLY, sm.getString("wsFrame.ioeTriggeredClose")); throw new WsIOException(cr); }
private static Object[] buildArgs(PojoPathParam[] pathParams, Map<String,String> pathParameters, Session session, EndpointConfig config, Throwable throwable, CloseReason closeReason) throws DecodeException { Object[] result = new Object[pathParams.length]; for (int i = 0; i < pathParams.length; i++) { Class<?> type = pathParams[i].getType(); if (type.equals(Session.class)) { result[i] = session; } else if (type.equals(EndpointConfig.class)) { result[i] = config; } else if (type.equals(Throwable.class)) { result[i] = throwable; } else if (type.equals(CloseReason.class)) { result[i] = closeReason; } else { String name = pathParams[i].getName(); String value = pathParameters.get(name); try { result[i] = Util.coerceToType(type, value); } catch (Exception e) { throw new DecodeException(value, sm.getString( "pojoMethodMapping.decodePathParamFail", value, type), e); } } } return result; }
private void onError(Throwable throwable) { wsSession.doClose(new CloseReason(CloseCodes.GOING_AWAY, throwable.getMessage()), new CloseReason(CloseCodes.CLOSED_ABNORMALLY, throwable.getMessage())); // Need to call onError using the web application's class loader Thread t = Thread.currentThread(); ClassLoader cl = t.getContextClassLoader(); t.setContextClassLoader(applicationClassLoader); try { ep.onError(wsSession, throwable); } finally { t.setContextClassLoader(cl); } }
@Override public void onDataAvailable() { try { wsFrame.onDataAvailable(); } catch (WsIOException ws) { wsProtocolHandler.close(ws.getCloseReason()); } catch (IOException ioe) { onError(ioe); CloseReason cr = new CloseReason( CloseCodes.CLOSED_ABNORMALLY, ioe.getMessage()); wsProtocolHandler.close(cr); } }
/** * Method will allow to close opened Web Socket Connection * * * @throws IOException */ public void close() throws Exception { log.info("Closing Web Socket Connection with - " + this.mc.getName() + "-" + this.mc.getIpAddress()); this.isInterrupted = true; // check if the initThread is still running interrupt that thread if (this.initThread != null && !this.initThread.isInterrupted()) { this.initThread.interrupt(); } if (this.wsSession != null && this.wsSession.isOpen()) { // wait until client finishes processing incoming messages then close this connection gracefully while (this.clientEndpoint.isProcessingMessage()) { try { wait(500); } catch (Exception e) { continue; } } WebSocketClient.this.wsSession.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "Closing Connection Because MC is either Removed or Updated")); } if (this.client.getExecutorService() != null) { this.client.getExecutorService().shutdownNow(); } if (this.client.getScheduledExecutorService() != null) { this.client.getScheduledExecutorService().shutdownNow(); } if (this.mgrApi != null) { this.mgrApi.close(); } // stop Ping thread... this.keepAliveThread.interrupt(); }
@OnOpen public void registerUser(Session websocket) throws IOException { Integer organisationId = Integer .valueOf(websocket.getRequestParameterMap().get(AttributeNames.PARAM_ORGANISATION_ID).get(0)); Integer userId = getUser(websocket).getUserId(); if (!KumaliveWebsocketServer.getSecurityService().hasOrgRole(organisationId, userId, new String[] { Role.GROUP_MANAGER, Role.MONITOR, Role.LEARNER }, "register on kumalive", false)) { // prevent unauthorised user from accessing Kumalive String warning = "User " + userId + " is not a monitor nor a learner of organisation " + organisationId; logger.warn(warning); websocket.close(new CloseReason(CloseCodes.CANNOT_ACCEPT, warning)); } }