use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.
the class StompSubProtocolHandler method convertConnectAcktoStompConnected.
/**
* The simple broker produces {@code SimpMessageType.CONNECT_ACK} that's not STOMP
* specific and needs to be turned into a STOMP CONNECTED frame.
*/
private StompHeaderAccessor convertConnectAcktoStompConnected(StompHeaderAccessor connectAckHeaders) {
String name = StompHeaderAccessor.CONNECT_MESSAGE_HEADER;
Message<?> message = (Message<?>) connectAckHeaders.getHeader(name);
if (message == null) {
throw new IllegalStateException("Original STOMP CONNECT not found in " + connectAckHeaders);
}
StompHeaderAccessor connectHeaders = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);
StompHeaderAccessor connectedHeaders = StompHeaderAccessor.create(StompCommand.CONNECTED);
Set<String> acceptVersions = connectHeaders.getAcceptVersion();
if (acceptVersions.contains("1.2")) {
connectedHeaders.setVersion("1.2");
} else if (acceptVersions.contains("1.1")) {
connectedHeaders.setVersion("1.1");
} else if (!acceptVersions.isEmpty()) {
throw new IllegalArgumentException("Unsupported STOMP version '" + acceptVersions + "'");
}
long[] heartbeat = (long[]) connectAckHeaders.getHeader(SimpMessageHeaderAccessor.HEART_BEAT_HEADER);
if (heartbeat != null) {
connectedHeaders.setHeartbeat(heartbeat[0], heartbeat[1]);
} else {
connectedHeaders.setHeartbeat(0, 0);
}
return connectedHeaders;
}
use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.
the class StompSubProtocolHandler method sendErrorMessage.
/**
* Invoked when no
* {@link #setErrorHandler(StompSubProtocolErrorHandler) errorHandler}
* is configured to send an ERROR frame to the client.
*/
private void sendErrorMessage(WebSocketSession session, Throwable error) {
StompHeaderAccessor headerAccessor = StompHeaderAccessor.create(StompCommand.ERROR);
headerAccessor.setMessage(error.getMessage());
byte[] bytes = this.stompEncoder.encode(headerAccessor.getMessageHeaders(), EMPTY_PAYLOAD);
try {
session.sendMessage(new TextMessage(bytes));
} catch (Throwable ex) {
// Could be part of normal workflow (e.g. browser tab closed)
logger.debug("Failed to send STOMP ERROR to client", ex);
}
}
use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.
the class StompSubProtocolHandler method handleMessageToClient.
/**
* Handle STOMP messages going back out to WebSocket clients.
*/
@Override
@SuppressWarnings("unchecked")
public void handleMessageToClient(WebSocketSession session, Message<?> message) {
if (!(message.getPayload() instanceof byte[])) {
if (logger.isErrorEnabled()) {
logger.error("Expected byte[] payload. Ignoring " + message + ".");
}
return;
}
StompHeaderAccessor accessor = getStompHeaderAccessor(message);
StompCommand command = accessor.getCommand();
if (StompCommand.MESSAGE.equals(command)) {
if (accessor.getSubscriptionId() == null && logger.isWarnEnabled()) {
logger.warn("No STOMP \"subscription\" header in " + message);
}
String origDestination = accessor.getFirstNativeHeader(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION);
if (origDestination != null) {
accessor = toMutableAccessor(accessor, message);
accessor.removeNativeHeader(SimpMessageHeaderAccessor.ORIGINAL_DESTINATION);
accessor.setDestination(origDestination);
}
} else if (StompCommand.CONNECTED.equals(command)) {
this.stats.incrementConnectedCount();
accessor = afterStompSessionConnected(message, accessor, session);
if (this.eventPublisher != null && StompCommand.CONNECTED.equals(command)) {
try {
SimpAttributes simpAttributes = new SimpAttributes(session.getId(), session.getAttributes());
SimpAttributesContextHolder.setAttributes(simpAttributes);
Principal user = getUser(session);
publishEvent(new SessionConnectedEvent(this, (Message<byte[]>) message, user));
} finally {
SimpAttributesContextHolder.resetAttributes();
}
}
}
byte[] payload = (byte[]) message.getPayload();
if (StompCommand.ERROR.equals(command) && getErrorHandler() != null) {
Message<byte[]> errorMessage = getErrorHandler().handleErrorMessageToClient((Message<byte[]>) message);
accessor = MessageHeaderAccessor.getAccessor(errorMessage, StompHeaderAccessor.class);
Assert.state(accessor != null, "Expected STOMP headers");
payload = errorMessage.getPayload();
}
sendToClient(session, accessor, payload);
}
use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.
the class RestTemplateXhrTransportTests method connectReceiveAndCloseWithStompFrame.
@Test
public void connectReceiveAndCloseWithStompFrame() throws Exception {
StompHeaderAccessor accessor = StompHeaderAccessor.create(StompCommand.SEND);
accessor.setDestination("/destination");
MessageHeaders headers = accessor.getMessageHeaders();
Message<byte[]> message = MessageBuilder.createMessage("body".getBytes(StandardCharsets.UTF_8), headers);
byte[] bytes = new StompEncoder().encode(message);
TextMessage textMessage = new TextMessage(bytes);
SockJsFrame frame = SockJsFrame.messageFrame(new Jackson2SockJsMessageCodec(), textMessage.getPayload());
String body = "o\n" + frame.getContent() + "\n" + "c[3000,\"Go away!\"]";
ClientHttpResponse response = response(HttpStatus.OK, body);
connect(response);
verify(this.webSocketHandler).afterConnectionEstablished(any());
verify(this.webSocketHandler).handleMessage(any(), eq(textMessage));
verify(this.webSocketHandler).afterConnectionClosed(any(), eq(new CloseStatus(3000, "Go away!")));
verifyNoMoreInteractions(this.webSocketHandler);
}
use of org.springframework.messaging.simp.stomp.StompHeaderAccessor in project spring-framework by spring-projects.
the class StompSubProtocolHandlerTests method handleMessageFromClient.
@Test
public void handleMessageFromClient() {
TextMessage textMessage = StompTextMessageBuilder.create(StompCommand.CONNECT).headers("login:guest", "passcode:guest", "accept-version:1.1,1.0", "heart-beat:10000,10000").build();
this.protocolHandler.afterSessionStarted(this.session, this.channel);
this.protocolHandler.handleMessageFromClient(this.session, textMessage, this.channel);
verify(this.channel).send(this.messageCaptor.capture());
Message<?> actual = this.messageCaptor.getValue();
assertNotNull(actual);
assertEquals("s1", SimpMessageHeaderAccessor.getSessionId(actual.getHeaders()));
assertNotNull(SimpMessageHeaderAccessor.getSessionAttributes(actual.getHeaders()));
assertNotNull(SimpMessageHeaderAccessor.getUser(actual.getHeaders()));
assertEquals("joe", SimpMessageHeaderAccessor.getUser(actual.getHeaders()).getName());
assertNotNull(SimpMessageHeaderAccessor.getHeartbeat(actual.getHeaders()));
assertArrayEquals(new long[] { 10000, 10000 }, SimpMessageHeaderAccessor.getHeartbeat(actual.getHeaders()));
StompHeaderAccessor stompAccessor = StompHeaderAccessor.wrap(actual);
assertEquals(StompCommand.CONNECT, stompAccessor.getCommand());
assertEquals("guest", stompAccessor.getLogin());
assertEquals("guest", stompAccessor.getPasscode());
assertArrayEquals(new long[] { 10000, 10000 }, stompAccessor.getHeartbeat());
assertEquals(new HashSet<>(Arrays.asList("1.1", "1.0")), stompAccessor.getAcceptVersion());
assertEquals(0, this.session.getSentMessages().size());
}
Aggregations