Spring Websocket:WebSocket握手期间出错:意外的响应代码:404

时间:2015-01-22 14:03:11

标签: spring-websocket

我实现了自己的基于Spring框架的Websocket应用程序并使用了相同的配置:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html

服务器端代码:

import org.springframework.context.annotation.Configuration;
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("/ws").withSockJS();
    }

}

客户端代码:* .jsp文件

        /*
         *connect to websocket
         */
        function connect() {
            var socket = new SockJS("<c:url value='/ws'/>");
            stompClient = Stomp.over(socket);
            stompClient.connect();
        }

        function disconnect() {
            stompClient.disconnect();
            setConnected(false);
            console.log("Disconnected");
        }

pom.xml依赖项:

        <!-- Spring websocket and messaging -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

该应用程序可以在Spring Tools Suite的Pivotal tc Server Developer Edition v3.0(使用Tomcat8.0.15炫目)或Tomcat7.0.53上运行。但是,当我将此应用程序部署到服务器时,websocket无法正常工作。控制台显示:

stomp.min.js:8 Opening Web Socket...
sockjs.min.js:27 WebSocket connection to 'ws://serverip/ws/331/xsooi48g/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
sockjs.min.js:27 POST http://serverip/ws/331/1mg08452/xhr_streaming 500 (Internal Server Error)
sockjs.min.js:27 POST http://serverip/ws/331/mmodvswk/xhr 500 (Internal Server Error)
stomp.min.js:8 Whoops! Lost connection to undefined

我有没有想念别的东西?

更新: Tomcat版本7.0.52.0 服务器端日志:

 WARN : org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService - Failed to create a default WebSocketTransportHandler
java.lang.IllegalStateException: No suitable default RequestUpgradeStrategy found
        at org.springframework.web.socket.server.support.DefaultHandshakeHandler.initRequestUpgradeStrategy(DefaultHandshakeHandler.java:127)
        at org.springframework.web.socket.server.support.DefaultHandshakeHandler.<init>(DefaultHandshakeHandler.java:96)
        at org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService.getDefaultTransportHandlers(DefaultSockJsService.java:88)
        at org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService.<init>(DefaultSockJsService.java:74)
        at org.springframework.web.socket.config.annotation.SockJsServiceRegistration.createSockJsService(SockJsServiceRegistration.java:286)
        at org.springframework.web.socket.config.annotation.SockJsServiceRegistration.getSockJsService(SockJsServiceRegistration.java:244)
        at org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration$StompSockJsServiceRegistration.getSockJsService(WebMvcStompWebSocketEndpointRegistration.java:161)
        at org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration.getMappings(WebMvcStompWebSocketEndpointRegistration.java:127)
        at org.springframework.web.socket.config.annotation.WebMvcStompEndpointRegistry.getHandlerMapping(WebMvcStompEndpointRegistry.java:142)
        at org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurationSupport.stompWebSocketHandlerMapping(WebSocketMessageBrokerConfigurationSupport.java:59)
        at org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration$$EnhancerBySpringCGLIB$$4b464c58.CGLIB$stompWebSocketHandlerMapping$9(<generated>)
        at org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration$$EnhancerBySpringCGLIB$$4b464c58$$FastClassBySpringCGLIB$$59d52b8d.invoke(<generated>)
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:309)
        at org.springframework.web.socket.config.annotation.DelegatingWebSocketMessageBrokerConfiguration$$EnhancerBySpringCGLIB$$4b464c58.stompWebSocketHandlerMapping(<generated>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:483)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:591)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1111)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1006)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:762)
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:106)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4973)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5467)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:632)
        at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1229)
        at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1875)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
INFO : org.springframework.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/ws/**] onto handler of type [class org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler]
INFO : org.springframework.context.support.DefaultLifecycleProcessor - Starting beans in phase 2147483647

1 个答案:

答案 0 :(得分:4)

在网络上没有解决方案的情况下试图解决相同的错误一周后,我设法解决它。

首先,改变一下:

registry.addEndpoint("/ws").withSockJS();

到此:

registry.addEndpoint("/ws")
.setHandshakeHandler(new DefaultHandshakeHandler(new TomcatRequestUpgradeStrategy()))
.withSockJS();

这使Tomcat接受websocket协议,因为它可以升级HTTP协议。

也许您正在使用Apache,因此您需要启用代理和wstunnel模块,因此您应该在终端上运行此命令:

$ sudo a2enmod proxy
$ sudo service apache2 restart
$ sudo a2enmod proxy_wstunnel
$ sudo service apache2 restart

你应该升级你的tomcat