无法使用 WebSocket 发送回复

Unable to send reply using WebSocket

我找了很多教程,我觉得一切都很好,但是客户端从来没有收到响应消息。连接正常,正在调用控制器上的方法,但客户端的订阅似乎被忽略了。

配置class:

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

}

控制器class:

@Controller
public class StatusController {
    @MessageMapping("/status")
    @SendTo("/topic/reply")
    public String status(@Payload String test) {
        return test;
    }
}

测试class:

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

}

我确信我遗漏了一些非常简单的东西,但我已经尝试了两天不同的配置但没有成功。

解决方案

看起来响应 class 需要有一个任何类型的字段 "content" 和一个对应的 getContent() (不知道 getContent() 是否真的有必要)。