@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 onApplicationEvent(ApplicationEvent event) { if (event instanceof SessionDestroyedEvent) { SessionDestroyedEvent e = (SessionDestroyedEvent) event; closeWsSessions(e.getSessionId()); } else if (event instanceof SessionConnectEvent) { SessionConnectEvent e = (SessionConnectEvent) event; afterConnectionEstablished(e.getWebSocketSession()); } else if (event instanceof SessionDisconnectEvent) { SessionDisconnectEvent e = (SessionDisconnectEvent) event; Map<String, Object> sessionAttributes = SimpMessageHeaderAccessor .getSessionAttributes(e.getMessage().getHeaders()); String httpSessionId = (sessionAttributes != null) ? SessionRepositoryMessageInterceptor.getSessionId(sessionAttributes) : null; afterConnectionClosed(httpSessionId, e.getSessionId()); } }
/** * Called when a web socket disconnects. We'll close out any consumers that web socket client had running * based on their sessionId. */ @EventListener void handleSessionDisconnect(final SessionDisconnectEvent event) { // Grab sessionId from event final String sessionId = event.getSessionId(); // Disconnect that sessionId's consumers webSocketConsumersManager.removeConsumersForSessionId(sessionId); } }
@EventListener public void handleWebSocketDisconnectListener(SessionDisconnectEvent event) { StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(event.getMessage()); String username = (String) headerAccessor.getSessionAttributes().get("username"); if(username != null) { logger.info("User Disconnected : " + username); ChatMessage chatMessage = new ChatMessage(); chatMessage.setType(ChatMessage.MessageType.LEAVE); chatMessage.setSender(username); messagingTemplate.convertAndSend("/topic/public", chatMessage); } } }
@Test public void removeSessionIds() { DefaultSimpUserRegistry registry = new DefaultSimpUserRegistry(); TestPrincipal user = new TestPrincipal("joe"); Message<byte[]> message = createMessage(SimpMessageType.CONNECT_ACK, "123"); SessionConnectedEvent connectedEvent = new SessionConnectedEvent(this, message, user); registry.onApplicationEvent(connectedEvent); message = createMessage(SimpMessageType.CONNECT_ACK, "456"); connectedEvent = new SessionConnectedEvent(this, message, user); registry.onApplicationEvent(connectedEvent); message = createMessage(SimpMessageType.CONNECT_ACK, "789"); connectedEvent = new SessionConnectedEvent(this, message, user); registry.onApplicationEvent(connectedEvent); SimpUser simpUser = registry.getUser("joe"); assertNotNull(simpUser); assertEquals(3, simpUser.getSessions().size()); CloseStatus status = CloseStatus.GOING_AWAY; message = createMessage(SimpMessageType.DISCONNECT, "456"); SessionDisconnectEvent disconnectEvent = new SessionDisconnectEvent(this, message, "456", status, user); registry.onApplicationEvent(disconnectEvent); message = createMessage(SimpMessageType.DISCONNECT, "789"); disconnectEvent = new SessionDisconnectEvent(this, message, "789", status, user); registry.onApplicationEvent(disconnectEvent); assertEquals(1, simpUser.getSessions().size()); assertNotNull(simpUser.getSession("123")); }
@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 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 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 afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception { Principal principal = webSocketSession.getPrincipal(); if (principal != null) { SimpMessageHeaderAccessor accessor = SimpMessageHeaderAccessor .create(SimpMessageType.MESSAGE); accessor.setSessionId(webSocketSession.getId()); publishEvent(new SessionDisconnectEvent(this, MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders()), webSocketSession.getId(), closeStatus, principal)); } super.afterConnectionClosed(webSocketSession, closeStatus); }
} else if (StompCommand.DISCONNECT.equals(accessor.getCommand())) { ((DefaultSimpUserRegistry) userRegistry).onApplicationEvent( new SessionDisconnectEvent(this, MessageBuilder.createMessage(new byte[] {}, accessor.getMessageHeaders()), accessor.getSessionId(), CloseStatus.NORMAL));