WebSocket握手期间出错(意外响应代码:400)

时间:2017-05-27 11:26:26

标签: java spring websocket apache2.4 sockjs

我的代码完全在localhost中工作,但当我将我的应用程序设置为服务器时,会发生此错误。

  

WebSocket连接到   'wss://url.com/webSocket/193/uj4s3xue/websocket'失败:错误期间   WebSocket握手:意外的响应代码:400

     

sockjs.min.js:2 POST   https://url.com/webSocket/193/e1vwalij/xhr_streaming?t=1495418202369   403(禁止)

Js代码:

   function connect() {
        var socket = new SockJS('/webSocket');
        stompClient = Stomp.over(socket);
        stompClient.connect({}, function (frame) {
            stompClient.debug = null;
            stompClient.subscribe('/topic/messages/' + vm.id, function (greeting) {
                refreshMessages(JSON.parse(greeting.body));
            });
        });
    } 

Java代码:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

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

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/webSocket").setAllowedOrigins("*").withSockJS();
    }

    @Bean
    public PresenceChannelInterceptor presenceChannelInterceptor() {
        return new PresenceChannelInterceptor();
    }

    @Override
    public void configureClientInboundChannel(ChannelRegistration registration) {
        registration.setInterceptors(presenceChannelInterceptor());
    }

    @Override
    public void configureClientOutboundChannel(ChannelRegistration registration) {
        registration.taskExecutor().corePoolSize(8);
        registration.setInterceptors(presenceChannelInterceptor());
    }
}

在春天服务器发生异常后:

  

2017-05-27 11:14:57.101 ERROR 51230 --- [XNIO-2 task-11]   o.s.w.s.s.s.DefaultHandshakeHandler:由于握手失败   无效的升级标题:null

     

2017-05-27 11:16:10.020 ERROR 51230 --- [MessageBroker-1]   o.s.s.s.TaskUtils $ LoggingErrorHandler:发生意外错误   在预定的任务中。

     

org.springframework.web.socket.sockjs.SockJsTransportFailureException:   无法写入SockJsFrame content ='h';嵌套异常是   java.io.IOException:断管道   org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame(AbstractSockJsSession.java:339)     在   org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.sendHeartbeat(AbstractSockJsSession.java:255)     在   org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession $ HeartbeatTask.run(AbstractSockJsSession.java:451)     在   org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)     在   java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:511)     在java.util.concurrent.FutureTask.run(FutureTask.java:266)at   java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.access $ 201(ScheduledThreadPoolExecutor.java:180)     在   java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)     在   java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)     在   java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:617)     在java.lang.Thread.run(Thread.java:748)引起:   java.io.IOException:断管道   sun.nio.ch.FileDispatcherImpl.writev0(Native Method)at   sun.nio.ch.SocketDispatcher.writev(SocketDispatcher.java:51)at   sun.nio.ch.IOUtil.write(IOUtil.java:148)at   sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:504)at   org.xnio.nio.NioSocketConduit.write(NioSocketConduit.java:161)at at   io.undertow.server.protocol.http.HttpResponseConduit.write(HttpResponseConduit.java:645)     在   io.undertow.conduits.ChunkedStreamSinkConduit.doWrite(ChunkedStreamSinkConduit.java:163)     在   io.undertow.conduits.ChunkedStreamSinkConduit.write(ChunkedStreamSinkConduit.java:127)     在   org.xnio.conduits.ConduitStreamSinkChannel.write(ConduitStreamSinkChannel.java:150)     在   io.undertow.channels.DetachableStreamSinkChannel.write(DetachableStreamSinkChannel.java:240)     在   io.undertow.server.HttpServerExchange $ WriteDispatchChannel.write(HttpServerExchange.java:2049)     在   io.undertow.servlet.spec.ServletOutputStreamImpl.writeBufferBlocking(ServletOutputStreamImpl.java:570)     在   io.undertow.servlet.spec.ServletOutputStreamImpl.flushInternal(ServletOutputStreamImpl.java:485)     在   io.undertow.servlet.spec.ServletOutputStreamImpl.flush(ServletOutputStreamImpl.java:472)     在   io.undertow.servlet.spec.HttpServletResponseImpl.flushBuffer(HttpServletResponseImpl.java:461)     在   javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:215)     在   javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:215)     在   org.springframework.security.web.util.OnCommittedResponseWrapper.flushBuffer(OnCommittedResponseWrapper.java:159)     在   javax.servlet.ServletResponseWrapper.flushBuffer(ServletResponseWrapper.java:215)     在   org.springframework.http.server.ServletServerHttpResponse.flush(ServletServerHttpResponse.java:96)     在   org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.writeFrameInternal(AbstractHttpSockJsSession.java:350)     在   org.springframework.web.socket.sockjs.transport.session.AbstractSockJsSession.writeFrame(AbstractSockJsSession.java:322)     ...省略了10个常见帧

Sever是apache2 web服务器。我该如何解决这个问题?。

1 个答案:

答案 0 :(得分:1)

我通过使用

激活ws_tunnel解决了这个问题
  

sudo a2enmod proxy_wstunnel

并在位于

中的apache 000-default-le-ssl.conf文件上创建RewriteEngine
  

/etc/apache2/sites-enabled/000-default-le-ssl.conf

  RewriteEngine On
    RewriteCond %{HTTP:Upgrade} =websocket [NC]
    RewriteRule /webSocket(.*)           ws://127.0.0.1:8080/webSocket/$1 [P,L]