@Override public String getId() { return this.delegate.getId(); }
@Nullable private Principal getUser(WebSocketSession session) { Principal user = this.stompAuthentications.get(session.getId()); return (user != null ? user : session.getPrincipal()); }
@Override public void close() { WebSocketSession session = this.session; if (session != null) { try { session.close(); } catch (IOException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to close session: " + session.getId(), ex); } } } } }
private void clearSession(WebSocketSession session, CloseStatus closeStatus) throws Exception { if (logger.isDebugEnabled()) { logger.debug("Clearing session " + session.getId()); } if (this.sessions.remove(session.getId()) != null) { this.stats.decrementSessionCount(session); } findProtocolHandler(session).afterSessionEnded(session, closeStatus, this.clientInboundChannel); }
private void registerWsSession(String httpSessionId, WebSocketSession wsSession) { Map<String, WebSocketSession> sessions = this.httpSessionIdToWsSessions .get(httpSessionId); if (sessions == null) { sessions = new ConcurrentHashMap<>(); this.httpSessionIdToWsSessions.putIfAbsent(httpSessionId, sessions); sessions = this.httpSessionIdToWsSessions.get(httpSessionId); } sessions.put(wsSession.getId(), wsSession); }
@Override public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus, MessageChannel outputChannel) { this.decoders.remove(session.getId()); Message<byte[]> message = createDisconnectMessage(session); SimpAttributes simpAttributes = SimpAttributes.fromMessage(message); try { SimpAttributesContextHolder.setAttributes(simpAttributes); if (this.eventPublisher != null) { Principal user = getUser(session); publishEvent(this.eventPublisher, new SessionDisconnectEvent(this, message, session.getId(), closeStatus, user)); } outputChannel.send(message); } finally { this.stompAuthentications.remove(session.getId()); SimpAttributesContextHolder.resetAttributes(); simpAttributes.sessionCompleted(); } }
@Override public void afterSessionStarted(WebSocketSession session, MessageChannel outputChannel) { if (session.getTextMessageSizeLimit() < MINIMUM_WEBSOCKET_MESSAGE_SIZE) { session.setTextMessageSizeLimit(MINIMUM_WEBSOCKET_MESSAGE_SIZE); } this.decoders.put(session.getId(), new BufferingStompDecoder(this.stompDecoder, getMessageSizeLimit())); }
@Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // WebSocketHandlerDecorator could close the session if (!session.isOpen()) { return; } this.stats.incrementSessionCount(session); session = decorateSession(session); this.sessions.put(session.getId(), new WebSocketSessionHolder(session)); findProtocolHandler(session).afterSessionStarted(session, this.clientInboundChannel); }
/** * Handle an inbound message from a WebSocket client. */ @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { WebSocketSessionHolder holder = this.sessions.get(session.getId()); if (holder != null) { session = holder.getSession(); } SubProtocolHandler protocolHandler = findProtocolHandler(session); protocolHandler.handleMessageFromClient(session, message, this.clientInboundChannel); if (holder != null) { holder.setHasHandledMessages(); } checkSessions(); }
BufferingStompDecoder decoder = this.decoders.get(session.getId()); if (decoder == null) { throw new IllegalStateException("No decoder for session id '" + session.getId() + "'"); if (logger.isErrorEnabled()) { logger.error("Failed to parse " + webSocketMessage + " in session " + session.getId() + ". Sending STOMP ERROR to client.", ex); Assert.state(headerAccessor != null, "No StompHeaderAccessor"); headerAccessor.setSessionId(session.getId()); headerAccessor.setSessionAttributes(session.getAttributes()); headerAccessor.setUser(getUser(session)); Principal user = headerAccessor.getUser(); if (user != null && user != session.getPrincipal()) { this.stompAuthentications.put(session.getId(), user); if (logger.isErrorEnabled()) { logger.error("Failed to send client message to application via MessageChannel" + " in session " + session.getId() + ". Sending STOMP ERROR to client.", ex);
logger.debug("Failed to send WebSocket message to client in session " + session.getId(), ex);
if (this.eventPublisher != null) { try { SimpAttributes simpAttributes = new SimpAttributes(session.getId(), session.getAttributes()); SimpAttributesContextHolder.setAttributes(simpAttributes); Principal user = getUser(session);
private Message<byte[]> createDisconnectMessage(WebSocketSession session) { StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.DISCONNECT); if (getHeaderInitializer() != null) { getHeaderInitializer().initHeaders(headerAccessor); } headerAccessor.setSessionId(session.getId()); headerAccessor.setSessionAttributes(session.getAttributes()); Principal user = getUser(session); if (user != null) { headerAccessor.setUser(user); } return MessageBuilder.createMessage(EMPTY_PAYLOAD, headerAccessor.getMessageHeaders()); }
@Override public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception { IntegrationWebSocketContainer.this.sessions.remove(session.getId()); throw new Exception(exception); }
@Before public void setup() { String sessionId = "session-id"; MapSession session = new MapSession(sessionId); this.attributes = new HashMap<>(); SessionRepositoryMessageInterceptor.setSessionId(this.attributes, sessionId); given(this.wsSession.getAttributes()).willReturn(this.attributes); given(this.wsSession.getPrincipal()).willReturn(this.principal); given(this.wsSession.getId()).willReturn("wsSession-id"); given(this.wsSession2.getAttributes()).willReturn(this.attributes); given(this.wsSession2.getPrincipal()).willReturn(this.principal); given(this.wsSession2.getId()).willReturn("wsSession-id2"); Map<String, Object> headers = new HashMap<>(); headers.put(SimpMessageHeaderAccessor.SESSION_ATTRIBUTES, this.attributes); given(this.message.getHeaders()).willReturn(new MessageHeaders(headers)); this.listener = new WebSocketRegistryListener(); this.connect = new SessionConnectEvent(this.listener, this.wsSession); this.connect2 = new SessionConnectEvent(this.listener, this.wsSession2); this.disconnect = new SessionDisconnectEvent(this.listener, this.message, this.wsSession.getId(), CloseStatus.NORMAL); this.deleted = new SessionDeletedEvent(this.listener, session); this.expired = new SessionExpiredEvent(this.listener, session); }
@Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { WebSocketSession removed = IntegrationWebSocketContainer.this.sessions.remove(session.getId()); if (removed != null) { if (IntegrationWebSocketContainer.this.messageListener != null) { IntegrationWebSocketContainer.this.messageListener.afterSessionEnded(session, closeStatus); } } }
@Override public void afterConnectionEstablished(WebSocketSession sessionToDecorate) throws Exception { // NOSONAR SF ifce WebSocketSession session = new ConcurrentWebSocketSessionDecorator(sessionToDecorate, IntegrationWebSocketContainer.this.sendTimeLimit, IntegrationWebSocketContainer.this.sendBufferSizeLimit); IntegrationWebSocketContainer.this.sessions.put(session.getId(), session); if (IntegrationWebSocketContainer.this.logger.isDebugEnabled()) { IntegrationWebSocketContainer.this.logger.debug("Started WebSocket session = " + session.getId() + ", number of sessions = " + IntegrationWebSocketContainer.this.sessions.size()); } if (IntegrationWebSocketContainer.this.messageListener != null) { IntegrationWebSocketContainer.this.messageListener.afterSessionStarted(session); } }
@Override public void destroy() throws Exception { try { // Notify sessions to stop flushing messages for (WebSocketSession session : this.sessions.values()) { try { session.close(CloseStatus.GOING_AWAY); } catch (Exception e) { this.logger.error("Failed to close session id '" + session.getId() + "': " + e.getMessage()); } } } finally { this.sessions.clear(); } }
@Override public void afterSessionStarted(WebSocketSession session) throws Exception { // NOSONAR Thrown from the delegate if (isActive()) { SubProtocolHandler protocolHandler = this.subProtocolHandlerRegistry.findProtocolHandler(session); protocolHandler.afterSessionStarted(session, this.subProtocolHandlerChannel); if (!this.server && protocolHandler instanceof StompSubProtocolHandler) { StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.CONNECT); accessor.setSessionId(session.getId()); accessor.setLeaveMutable(true); accessor.setAcceptVersion("1.1,1.2"); Message<?> connectMessage = MessageBuilder.createMessage(EMPTY_PAYLOAD, accessor.getMessageHeaders()); protocolHandler.handleMessageToClient(session, connectMessage); } } }
@Override public void handleMessageFromClient(WebSocketSession session, WebSocketMessage<?> webSocketMessage, MessageChannel outputChannel) throws Exception { SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.create(SimpMessageType.MESSAGE); headerAccessor.setSessionId(session.getId()); headerAccessor.setSessionAttributes(session.getAttributes()); headerAccessor.setUser(session.getPrincipal()); headerAccessor.setHeader("content-length", webSocketMessage.getPayloadLength()); headerAccessor.setLeaveMutable(true); Message<?> message = MessageBuilder.createMessage(webSocketMessage.getPayload(), headerAccessor.getMessageHeaders()); try { SimpAttributesContextHolder.setAttributesFromMessage(message); outputChannel.send(message); } finally { SimpAttributesContextHolder.resetAttributes(); } }