Search in sources :

Example 1 with StompHeaderAccessor

use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.

the class SimpMessagingTemplateTests method doSendWithStompHeaders.

@Test
public void doSendWithStompHeaders() {
    StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SUBSCRIBE);
    accessor.setDestination("/user/queue/foo");
    Message<?> message = MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
    this.messagingTemplate.doSend("/queue/foo-user123", message);
    List<Message<byte[]>> messages = this.messageChannel.getMessages();
    Message<byte[]> sentMessage = messages.get(0);
    MessageHeaderAccessor sentAccessor = MessageHeaderAccessor.getAccessor(sentMessage, MessageHeaderAccessor.class);
    assertEquals(StompHeaderAccessor.class, sentAccessor.getClass());
    assertEquals("/queue/foo-user123", ((StompHeaderAccessor) sentAccessor).getDestination());
}
Also used : Message(org.springframework.messaging.Message) NativeMessageHeaderAccessor(org.springframework.messaging.support.NativeMessageHeaderAccessor) MessageHeaderAccessor(org.springframework.messaging.support.MessageHeaderAccessor) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) Test(org.junit.Test)

Example 2 with StompHeaderAccessor

use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.

the class UserDestinationMessageHandlerTests method handleMessageFromBrokerWithoutActiveSession.

@Test
public void handleMessageFromBrokerWithoutActiveSession() {
    this.handler.setBroadcastDestination("/topic/unresolved");
    given(this.brokerChannel.send(Mockito.any(Message.class))).willReturn(true);
    StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.MESSAGE);
    accessor.setSessionId("system123");
    accessor.setDestination("/topic/unresolved");
    accessor.setNativeHeader(ORIGINAL_DESTINATION, "/user/joe/queue/foo");
    accessor.setLeaveMutable(true);
    byte[] payload = "payload".getBytes(StandardCharsets.UTF_8);
    this.handler.handleMessage(MessageBuilder.createMessage(payload, accessor.getMessageHeaders()));
    // No re-broadcast
    verifyNoMoreInteractions(this.brokerChannel);
}
Also used : Message(org.springframework.messaging.Message) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) Test(org.junit.Test)

Example 3 with StompHeaderAccessor

use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.

the class StompSubProtocolHandler method handleMessageFromClient.

/**
	 * Handle incoming WebSocket messages from clients.
	 */
public void handleMessageFromClient(WebSocketSession session, WebSocketMessage<?> webSocketMessage, MessageChannel outputChannel) {
    List<Message<byte[]>> messages;
    try {
        ByteBuffer byteBuffer;
        if (webSocketMessage instanceof TextMessage) {
            byteBuffer = ByteBuffer.wrap(((TextMessage) webSocketMessage).asBytes());
        } else if (webSocketMessage instanceof BinaryMessage) {
            byteBuffer = ((BinaryMessage) webSocketMessage).getPayload();
        } else {
            return;
        }
        BufferingStompDecoder decoder = this.decoders.get(session.getId());
        if (decoder == null) {
            throw new IllegalStateException("No decoder for session id '" + session.getId() + "'");
        }
        messages = decoder.decode(byteBuffer);
        if (messages.isEmpty()) {
            if (logger.isTraceEnabled()) {
                logger.trace("Incomplete STOMP frame content received in session " + session + ", bufferSize=" + decoder.getBufferSize() + ", bufferSizeLimit=" + decoder.getBufferSizeLimit() + ".");
            }
            return;
        }
    } catch (Throwable ex) {
        if (logger.isErrorEnabled()) {
            logger.error("Failed to parse " + webSocketMessage + " in session " + session.getId() + ". Sending STOMP ERROR to client.", ex);
        }
        handleError(session, ex, null);
        return;
    }
    for (Message<byte[]> message : messages) {
        try {
            StompHeaderAccessor headerAccessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
            headerAccessor.setSessionId(session.getId());
            headerAccessor.setSessionAttributes(session.getAttributes());
            headerAccessor.setUser(getUser(session));
            headerAccessor.setHeader(SimpMessageHeaderAccessor.HEART_BEAT_HEADER, headerAccessor.getHeartbeat());
            if (!detectImmutableMessageInterceptor(outputChannel)) {
                headerAccessor.setImmutable();
            }
            if (logger.isTraceEnabled()) {
                logger.trace("From client: " + headerAccessor.getShortLogMessage(message.getPayload()));
            }
            boolean isConnect = StompCommand.CONNECT.equals(headerAccessor.getCommand());
            if (isConnect) {
                this.stats.incrementConnectCount();
            } else if (StompCommand.DISCONNECT.equals(headerAccessor.getCommand())) {
                this.stats.incrementDisconnectCount();
            }
            try {
                SimpAttributesContextHolder.setAttributesFromMessage(message);
                boolean sent = outputChannel.send(message);
                if (sent) {
                    if (isConnect) {
                        Principal user = headerAccessor.getUser();
                        if (user != null && user != session.getPrincipal()) {
                            this.stompAuthentications.put(session.getId(), user);
                        }
                    }
                    if (this.eventPublisher != null) {
                        if (isConnect) {
                            publishEvent(new SessionConnectEvent(this, message, getUser(session)));
                        } else if (StompCommand.SUBSCRIBE.equals(headerAccessor.getCommand())) {
                            publishEvent(new SessionSubscribeEvent(this, message, getUser(session)));
                        } else if (StompCommand.UNSUBSCRIBE.equals(headerAccessor.getCommand())) {
                            publishEvent(new SessionUnsubscribeEvent(this, message, getUser(session)));
                        }
                    }
                }
            } finally {
                SimpAttributesContextHolder.resetAttributes();
            }
        } catch (Throwable ex) {
            if (logger.isErrorEnabled()) {
                logger.error("Failed to send client message to application via MessageChannel" + " in session " + session.getId() + ". Sending STOMP ERROR to client.", ex);
            }
            handleError(session, ex, message);
        }
    }
}
Also used : TextMessage(org.springframework.web.socket.TextMessage) Message(org.springframework.messaging.Message) WebSocketMessage(org.springframework.web.socket.WebSocketMessage) BinaryMessage(org.springframework.web.socket.BinaryMessage) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) ByteBuffer(java.nio.ByteBuffer) BinaryMessage(org.springframework.web.socket.BinaryMessage) BufferingStompDecoder(org.springframework.messaging.simp.stomp.BufferingStompDecoder) TextMessage(org.springframework.web.socket.TextMessage) Principal(java.security.Principal)

Example 4 with StompHeaderAccessor

use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.

the class StompSubProtocolHandler method handleError.

private void handleError(WebSocketSession session, Throwable ex, Message<byte[]> clientMessage) {
    if (getErrorHandler() == null) {
        sendErrorMessage(session, ex);
        return;
    }
    Message<byte[]> message = getErrorHandler().handleClientMessageProcessingError(clientMessage, ex);
    if (message == null) {
        return;
    }
    StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
    Assert.state(accessor != null, "Expected STOMP headers");
    sendToClient(session, accessor, message.getPayload());
}
Also used : StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor)

Example 5 with StompHeaderAccessor

use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.

the class WebSocketMessageBrokerConfigurationSupportTests method clientInboundChannelSendMessage.

@Test
public void clientInboundChannelSendMessage() throws Exception {
    ApplicationContext config = createConfig(TestChannelConfig.class, TestConfigurer.class);
    TestChannel channel = config.getBean("clientInboundChannel", TestChannel.class);
    SubProtocolWebSocketHandler webSocketHandler = config.getBean(SubProtocolWebSocketHandler.class);
    List<ChannelInterceptor> interceptors = channel.getInterceptors();
    assertEquals(ImmutableMessageChannelInterceptor.class, interceptors.get(interceptors.size() - 1).getClass());
    TestWebSocketSession session = new TestWebSocketSession("s1");
    session.setOpen(true);
    webSocketHandler.afterConnectionEstablished(session);
    TextMessage textMessage = StompTextMessageBuilder.create(StompCommand.SEND).headers("destination:/foo").build();
    webSocketHandler.handleMessage(session, textMessage);
    Message<?> message = channel.messages.get(0);
    StompHeaderAccessor accessor = StompHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
    assertNotNull(accessor);
    assertFalse(accessor.isMutable());
    assertEquals(SimpMessageType.MESSAGE, accessor.getMessageType());
    assertEquals("/foo", accessor.getDestination());
}
Also used : ApplicationContext(org.springframework.context.ApplicationContext) AnnotationConfigApplicationContext(org.springframework.context.annotation.AnnotationConfigApplicationContext) TestWebSocketSession(org.springframework.web.socket.handler.TestWebSocketSession) SubProtocolWebSocketHandler(org.springframework.web.socket.messaging.SubProtocolWebSocketHandler) ChannelInterceptor(org.springframework.messaging.support.ChannelInterceptor) ImmutableMessageChannelInterceptor(org.springframework.messaging.support.ImmutableMessageChannelInterceptor) StompHeaderAccessor(org.springframework.messaging.simp.stomp.StompHeaderAccessor) TextMessage(org.springframework.web.socket.TextMessage) Test(org.junit.Test)

Aggregations

StompHeaderAccessor (org.springframework.messaging.simp.stomp.StompHeaderAccessor)38 Test (org.junit.Test)28 TextMessage (org.springframework.web.socket.TextMessage)19 Message (org.springframework.messaging.Message)10 BinaryMessage (org.springframework.web.socket.BinaryMessage)9 SimpMessageHeaderAccessor (org.springframework.messaging.simp.SimpMessageHeaderAccessor)6 WebSocketMessage (org.springframework.web.socket.WebSocketMessage)5 StompEncoder (org.springframework.messaging.simp.stomp.StompEncoder)4 StompHeaders (org.springframework.messaging.simp.stomp.StompHeaders)3 PongMessage (org.springframework.web.socket.PongMessage)3 Principal (java.security.Principal)2 MessageHeaders (org.springframework.messaging.MessageHeaders)2 SimpAttributes (org.springframework.messaging.simp.SimpAttributes)2 SimpAnnotationMethodMessageHandler (org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler)2 MessageHeaderAccessor (org.springframework.messaging.support.MessageHeaderAccessor)2 ByteBuffer (java.nio.ByteBuffer)1 ApplicationContext (org.springframework.context.ApplicationContext)1 ApplicationEventPublisher (org.springframework.context.ApplicationEventPublisher)1 AnnotationConfigApplicationContext (org.springframework.context.annotation.AnnotationConfigApplicationContext)1 ClientHttpResponse (org.springframework.http.client.ClientHttpResponse)1