/** * Register a sub-protocol handler. */ public void addProtocolHandler(SubProtocolHandler handler) { List<String> protocols = handler.getSupportedProtocols(); if (CollectionUtils.isEmpty(protocols)) { if (logger.isErrorEnabled()) { logger.error("No sub-protocols for " + handler); } return; } for (String protocol : protocols) { SubProtocolHandler replaced = this.protocolHandlerLookup.put(protocol, handler); if (replaced != null && replaced != handler) { throw new IllegalStateException("Cannot map " + handler + " to protocol '" + protocol + "': already mapped to " + replaced + "."); } } this.protocolHandlers.add(handler); }
@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); }
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); }
@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); } } }
findProtocolHandler(session).handleMessageToClient(session, message);
@Nullable private String resolveSessionId(Message<?> message) { for (SubProtocolHandler handler : this.protocolHandlerLookup.values()) { String sessionId = handler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } if (this.defaultProtocolHandler != null) { String sessionId = this.defaultProtocolHandler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } return null; }
/** * 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(); }
@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); } } }
() -> "The message converter '" + this.messageConverter + "' produced no message to send based on the request message: '" + message + "'"); this.subProtocolHandlerRegistry.findProtocolHandler(session).handleMessageToClient(session, messageToSend);
/** * Resolves the {@code sessionId} for the given {@code message} using * the {@link SubProtocolHandler#resolveSessionId} algorithm. * @param message The message to resolve the {@code sessionId} from. * @return The sessionId or {@code null}, if no one {@link SubProtocolHandler} * can't resolve it against provided {@code message}. */ public String resolveSessionId(Message<?> message) { for (SubProtocolHandler handler : this.protocolHandlers.values()) { String sessionId = handler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } if (this.defaultProtocolHandler != null) { String sessionId = this.defaultProtocolHandler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } return null; }
@Override public void onMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage) throws Exception { // NOSONAR Thrown from the delegate if (isActive()) { this.subProtocolHandlerRegistry.findProtocolHandler(session) .handleMessageFromClient(session, webSocketMessage, this.subProtocolHandlerChannel); } }
@Before public void setup() { MockitoAnnotations.initMocks(this); this.webSocketHandler = new SubProtocolWebSocketHandler(this.inClientChannel, this.outClientChannel); given(stompHandler.getSupportedProtocols()).willReturn(Arrays.asList("v10.stomp", "v11.stomp", "v12.stomp")); given(mqttHandler.getSupportedProtocols()).willReturn(Arrays.asList("MQTT")); this.session = new TestWebSocketSession(); this.session.setId("1"); this.session.setOpen(true); }
@Test public void nullSubProtocol() throws Exception { this.webSocketHandler.setDefaultProtocolHandler(defaultHandler); this.webSocketHandler.afterConnectionEstablished(session); verify(this.defaultHandler).afterSessionStarted( isA(ConcurrentWebSocketSessionDecorator.class), eq(this.inClientChannel)); verify(this.stompHandler, times(0)).afterSessionStarted(session, this.inClientChannel); verify(this.mqttHandler, times(0)).afterSessionStarted(session, this.inClientChannel); }
private void produceConnectAckMessage(Message<?> message, SimpMessageHeaderAccessor headerAccessor) { String sessionId = headerAccessor.getSessionId(); SimpMessageHeaderAccessor connectAck = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT_ACK); connectAck.setSessionId(sessionId); connectAck.setHeader(SimpMessageHeaderAccessor.CONNECT_MESSAGE_HEADER, message); Message<byte[]> ackMessage = MessageBuilder.createMessage(EMPTY_PAYLOAD, connectAck.getMessageHeaders()); WebSocketSession session = this.webSocketContainer.getSession(sessionId); try { this.subProtocolHandlerRegistry.findProtocolHandler(session).handleMessageToClient(session, ackMessage); } catch (Exception e) { throw new MessageHandlingException(message, "Error sending connect ack message", e); } }
@Override public void afterSessionEnded(WebSocketSession session, CloseStatus closeStatus) throws Exception { // NOSONAR Thrown from the delegate if (isActive()) { this.subProtocolHandlerRegistry.findProtocolHandler(session) .afterSessionEnded(session, closeStatus, this.subProtocolHandlerChannel); } }
@Nullable private String resolveSessionId(Message<?> message) { for (SubProtocolHandler handler : this.protocolHandlerLookup.values()) { String sessionId = handler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } if (this.defaultProtocolHandler != null) { String sessionId = this.defaultProtocolHandler.resolveSessionId(message); if (sessionId != null) { return sessionId; } } return null; }
@Override public void onMessage(WebSocketSession session, WebSocketMessage<?> webSocketMessage) throws Exception { // NOSONAR Thrown from the delegate if (isActive()) { this.subProtocolHandlerRegistry.findProtocolHandler(session) .handleMessageFromClient(session, webSocketMessage, this.subProtocolHandlerChannel); } }
List<String> protocols = handler.getSupportedProtocols(); if (CollectionUtils.isEmpty(protocols)) { if (LOGGER.isWarnEnabled()) { this.defaultProtocolHandler = defaultProtocolHandler; if (this.protocolHandlers.isEmpty() && this.defaultProtocolHandler != null) { List<String> protocols = this.defaultProtocolHandler.getSupportedProtocols(); for (String protocol : protocols) { SubProtocolHandler replaced = this.protocolHandlers.put(protocol, this.defaultProtocolHandler);
@Test public void emptySubProtocol() throws Exception { this.session.setAcceptedProtocol(""); this.webSocketHandler.setDefaultProtocolHandler(this.defaultHandler); this.webSocketHandler.afterConnectionEstablished(session); verify(this.defaultHandler).afterSessionStarted( isA(ConcurrentWebSocketSessionDecorator.class), eq(this.inClientChannel)); verify(this.stompHandler, times(0)).afterSessionStarted(session, this.inClientChannel); verify(this.mqttHandler, times(0)).afterSessionStarted(session, this.inClientChannel); }
findProtocolHandler(session).handleMessageToClient(session, message);