Невозможно отправить ответ с помощью WebSocket - PullRequest
0 голосов
/ 12 ноября 2018

Я нашел много учебников, и все выглядит правильно, но клиент никогда не получает ответное сообщение. Соединение работает, и вызывается метод на контроллере, но подписка клиента выглядит так, как будто она игнорируется.

Класс конфигурации:

@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;
    }

}

Я уверен, что мне не хватает чего-то очень простого, но я два дня безуспешно пробовал разные конфигурации.

1 Ответ

0 голосов
/ 14 ноября 2018

Решение

Похоже, что класс ответа должен иметь поле "content" любого типа и соответствующий метод getContent () (не знаю, действительно ли getContent ()nessessary).

...