Я нашел много учебников, и все выглядит правильно, но клиент никогда не получает ответное сообщение. Соединение работает, и вызывается метод на контроллере, но подписка клиента выглядит так, как будто она игнорируется.
Класс конфигурации:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/app");
registry.enableSimpleBroker("/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) {
stompEndpointRegistry.addEndpoint("/unify")
.withSockJS();
}
}
Класс контроллера:
@Controller
public class StatusController {
@MessageMapping("/status")
@SendTo("/topic/reply")
public String status(@Payload String test) {
return test;
}
}
Тестовый класс:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebSocketConnectionTest {
@Value(${local.server.port})
private String port;
@Test
public void testResponse() {
SockJsClient sockJsClient = new SockJsClient(createTransportClient());
WebSocketStompClient stompClient = new WebSocketStompClient(sockJsClient);
stompClient.setMessageConverter(new MappingJackson2MessageConverter());
boolean exceptionThrowed = false;
final CompletableFuture<String> completableFuture = new CompletableFuture<>();
try {
StompSession session = stompClient.connect("ws://localhost: " + port + "/unify", new StompSessionHandlerAdapter() {}).get(1, TimeUnit.SECONDS);
session.subscribe("/topic/reply", new StompFrameHandler() {
@Override
public Type getPayloadType(StompHeaders headers) {
return String.class;
}
@Override
public void handleFrame(StompHeaders headers, Object payload) {
completableFuture.complete((String)payload);
}
});
session.send("/app/status", "test");
// Always fails
String resp = completableFuture.get(5, TimeUnit.SECONDS);
} catch (InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace(); // Always timeout exception
exceptionThrowed = true;
}
Assert.assertFalse(exceptionThrowed);
}
private List<Transport> createTransportClient() {
List<Transport> transports = new ArrayList<>(1);
transports.add(new WebSocketTransport(new StandardWebSocketClient()));
return transports;
}
}
Я уверен, что мне не хватает чего-то очень простого, но я два дня безуспешно пробовал разные конфигурации.