【问题标题】:Very basic Spring websocket returns 404非常基本的 Spring websocket 返回 404
【发布时间】:2016-11-11 22:15:18
【问题描述】:

我正在学习使用 Spring WebSockets,但我无法获得一个非常基本的示例来工作,我收到 404 错误。 我使用http://docs.spring.io/spring/docs/current/spring-framework-reference/html/websocket.html 作为参考。

WebSocket 配置:

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    private Logger logger = Logger.getLogger(WebSocketConfig.class);

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        logger.debug("Registering websocket handler");
        registry.addHandler(gameWebSocketHandler(), "/StreamGame/ws/play");
    }

    @Bean
    public WebSocketHandler gameWebSocketHandler() {
        return new GameWebSocketHandler();
    }
}

WebSocketHandler:

public class GameWebSocketHandler extends TextWebSocketHandler {
    final static Logger logger = Logger.getLogger(GameWebSocketHandler.class);

    public GameWebSocketHandler() {
        logger.debug("Constructor handler");
    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
        super.handleTransportError(session, exception);
        logger.error("Transport error: " + exception.getMessage());
    }

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        logger.info("Handle message received: " + message.getPayload());
        //session.sendMessage(new TextMessage("Here is your answer"));
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        super.afterConnectionEstablished(session);
        logger.info("Connection established!");
    }
}

除非我弄错了,否则我应该能够通过 websocket 从客户端向服务器发送消息,如下所示:

sock = new WebSocket('ws://localhost:8080/StreamGame/ws/play');

我在连接时收到以下错误:

WebSocket 握手期间出错:意外响应代码:404WrappedWebSocket @ VM84:35(匿名函数)@(索引):11j @ jquery-3.1.1.min.js:2k @ jquery-3.1.1.min.js: 2 (index):26 错误未定义

Web.xml 包含以下内容:

   <!-- Processes application requests -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/application-context.xml</param-value>
    </context-param>

    <listener>
       <listener-class>
            org.springframework.web.context.ContextLoaderListener
       </listener-class>
    </listener> 
    <servlet>
        <servlet-name>SpringMVCDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/application-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Mapping websocket to spring dispatcher servlet -->
    <servlet-mapping>
        <servlet-name>SpringMVCDispatcherServlet</servlet-name>
        <url-pattern>/ws/*</url-pattern>
    </servlet-mapping>

我的 Spring 应用上下文包含:

连接 websocket 时,我在服务器日志中看到以下内容:

>     2016-11-13 TRACE - 39804 - org.springframework.web.servlet.DispatcherServlet -
> http-nio-8080-exec-2 - Bound request context to thread:
> org.apache.catalina.connector.RequestFacade@df5f117
>     2016-11-13 DEBUG - 39804 - org.springframework.web.servlet.DispatcherServlet -
> http-nio-8080-exec-2 - DispatcherServlet with name
> 'SpringMVCDispatcherServlet' processing GET request for
> [/StreamGame/ws/play]
>     2016-11-13 TRACE - 39804 - org.springframework.web.servlet.DispatcherServlet -
> http-nio-8080-exec-2 - Testing handler map
> [org.springframework.web.socket.server.support.WebSocketHandlerMapping@4e92ebf3]
> in DispatcherServlet with name 'SpringMVCDispatcherServlet'
>     2016-11-13 TRACE - 39804 - org.springframework.web.socket.server.support.WebSocketHandlerMapping
> - http-nio-8080-exec-2 - No handler mapping found for [/play]
>     2016-11-13 WARN  - 39804 - org.springframework.web.servlet.PageNotFound - http-nio-8080-exec-2 -
> No mapping found for HTTP request with URI [/StreamGame/ws/play] in
> DispatcherServlet with name 'SpringMVCDispatcherServlet'

【问题讨论】:

    标签: java websocket


    【解决方案1】:

    您的 websocket 网址似乎不正确。您将 /play 注册为处理程序,但调用 /StreamGame/play

    另外请记住,ws 连接是异步创建的,因此您必须等待连接握手完成才能发送消息,如下所示:

    var ws = new WebSocket("ws://localhost:8080/play");
    ws.onopen = function() {
        ws.send('AHOIHOI');
    }
    ws.onerror = function(error) {
        // handle connection error
    }
    

    【讨论】:

    • 您好,感谢您的建议。我尝试将 websocket 配置更改为 /StreamGame/play,但结果相同:registry.addHandler(gameWebSocketHandler(), "/StreamGame/play");
    • 好的,如果你的类没有被实例化,那么它就不能工作。您是否使用 Spring-Boot 来设置应用程序?如果没有,您可能忘记正确设置组件扫描类路径。
    • 嗨 Quagaar,我将 application-context.xml 和 web.xml 添加到我的原始帖子中。我需要在 web.xml 中定义更多内容吗?
    • 如果混合使用 xml 和 Java 配置,则必须将以下内容添加到应用程序上下文 xml:
    • 感谢 Quagaar,我添加了 annotation-config 标签,还添加了 websocket 请求到 SpringDispatcherServlet 的映射。我现在可以看到我在处理程序构造函数中添加的日志记录。所以他们现在被实例化了,但是 websocket 连接仍然返回 404 :(。我在日志中看到了以下内容:映射 URL 路径 [/StreamGame/play] 到类型 [class org.springframework.web.socket. server.support.WebSocketHttpRequestHandler]
    【解决方案2】:

    addHandler 函数需要映射到'/play',所以不包括根上下文(StreamGame)和调度器映射(/ws)。更改 addHandler 解决了这个问题:

    registry.addHandler(gameWebSocketHandler(), "/play");
    

    打开时连接的websocket如下:

    sock = new WebSocket('ws://localhost:8080/StreamGame/ws/play');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-28
      • 1970-01-01
      • 2011-05-21
      • 2015-12-11
      • 2019-10-22
      • 1970-01-01
      相关资源
      最近更新 更多