【问题标题】:Error during WebSocket handshake: Unexpected response code: 400 when using Spring Websocket, Stomp, SockJS in OpenshiftWebSocket 握手期间出错:意外响应代码:在 Openshift 中使用 Spring Websocket、Stomp、SockJS 时出现 400
【发布时间】:2017-04-30 13:51:28
【问题描述】:

根据我目前在互联网上搜索时了解到的情况,openshift 仅提供端口 8000 用于通过 HTTP 打开 Web 套接字连接。

我不知道如何使它适用于带有 Stomp 和 SockJs 的 Spring WebSocket 实现。这是我的代码sn-p,

Websocket 客户端实现:

function connect() {
        var socket = new SockJS('http://jbossews-nabac.rhcloud.com:8000/portal/ws');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function(frame) {
            setConnected(true);
            console.log('Connected: ' + frame);
            stompClient.subscribe('/queue/reply/${pageContext.session.id}', function(greeting) {
                showGreeting(greeting.body);
            });
        });
    }

WebSocket 服务器端配置:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketDefaultConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic/", "/queue/");
        config.setApplicationDestinationPrefixes("/portal");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
        .withSockJS()
        .setInterceptors(httpSessionIdHandshakeInterceptor());
    }

    @Bean
    public HttpSessionIdHandshakeInterceptor httpSessionIdHandshakeInterceptor() {
        return new HttpSessionIdHandshakeInterceptor();
    }

}

Chrome Console

如果我尝试这种方式,

var socket = new SockJS('/portal/ws');

我得到的错误是,

Chrome Console

请帮我解决这个错误。

【问题讨论】:

  • 这个问题你解决了吗?如果是,您能分享一下您的答案吗?

标签: spring websocket openshift stomp sockjs


【解决方案1】:

我遇到了同样的问题,最后,经过很长时间,我设法在 Openshift V3 中使用了 Spring WebSocket,但我认为这个解决方案也适用于较旧的 Openshift V2。

唯一的妥协是不使用 SockJS,而是使用标准的 WebSocket API。

在您的情况下,您必须在方法 registerStompEndpoints remove .withSockJS() 中编辑端点路径,添加后缀“/websocket”并将允许的来源设置为“*”(可能后者不是强制性的)。

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketDefaultConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic/", "/queue/");
        config.setApplicationDestinationPrefixes("/portal");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws/websocket")
        .setAllowedOrigins(‌​"*")
        .setInterceptors(httpSessionIdHandshakeInterceptor());
    }

    @Bean
    public HttpSessionIdHandshakeInterceptor httpSessionIdHandshakeInterceptor() {
        return new HttpSessionIdHandshakeInterceptor();
    }
}

在客户端,如前所述,您必须使用 WebSocket API 而不是 SockJS,并使用新路径连接到端点。

function connect() {
    var socket = new WebSocket('ws://your_service_exposed_route:80/portal/ws/websocket');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function(frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/queue/reply/${pageContext.session.id}', function(greeting) {
            showGreeting(greeting.body);
        });
    });
}

如您所见,我使用了端口 80:OpenShift V3 支持在同一端口上运行 WebSocket。当服务通过路由公开时,该端口将是外部的 80 端口,用于 HTTP 流量,包括 WebSockets。

就是这样!

【讨论】:

    猜你喜欢
    • 2017-03-15
    • 1970-01-01
    • 2019-08-05
    • 2021-04-09
    • 2016-05-12
    • 2014-05-15
    • 1970-01-01
    • 2019-06-25
    • 2015-07-22
    相关资源
    最近更新 更多