【问题标题】:Stomp over socket using sockjs can't connect with Spring 4 WebSocket使用 sockjs 踩过套接字无法与 Spring 4 WebSocket 连接
【发布时间】:2014-04-24 06:02:09
【问题描述】:

尝试使用 Spring 4 WebSocket 和 STOMP over socket 使用 sockjs。 我遇到了一个问题。

我的配置:

websocket.xml - spring 上下文的一部分

<websocket:message-broker application-destination-prefix="/app">  
    <websocket:stomp-endpoint path="/ws">                         
        <websocket:sockjs/>                                       
    </websocket:stomp-endpoint>                                   
    <websocket:simple-broker prefix="/topic"/>                    
</websocket:message-broker>       

控制器代码:

@MessageMapping("/ws")
@SendTo("/topic/ws")
public AjaxResponse hello() throws Exception {
    AjaxResponse ajaxResponse = new AjaxResponse();
    ajaxResponse.setSuccess(true);
    ajaxResponse.addSuccessMessage("WEB SOCKET!!! HELL YEAH!");
    return ajaxResponse;
}

客户端:

var socket = new SockJS("<c:url value='/ws'/>");               
var stompClient = Stomp.over(socket);                             
stompClient.connect({}, function(frame) {                         
    alert('Connected: ' + frame);                                 
    stompClient.send("/app/ws", {}, {});                       
    stompClient.subscribe('/topic/ws', function(response){ 
        alert(response.success);                                  
    });                                                           
});                                                               

输出:

Opening Web Socket... stomp.js:130
GET http://localhost:8080/ws/info 404 (Not Found) sockjs-0.3.js:807
Whoops! Lost connection to undefined stomp.js:130

我做错了什么?

我在 google 中找到了示例(TickerStocks 或类似的东西,问候应用程序(Spring 的示例)),所有这些都给了我同样的错误。我尝试使用带有握手的 WebSocket(没有 sockjs) - 结果相同)。

补充信息:

方法public AjaxResponse hello(); 放置在根上下文“/”上的IndexController 中。所以我可以提供完整路径:http://localhost:8080/ws。 部署经过测试的tomcat7和tomcat8。

【问题讨论】:

  • 不是很相关,但我强烈建议您放弃使用基于 XML 的配置文件,并在全局范围内采用 JavaConfig,而不是混合和匹配。 There is a complete tutorial 使用 JavaConfig 和 sockjs 进行设置。更重要的是,您的应用程序是如何部署的?它位于网络服务器的根目录?因为您在 Javascript 中的 URL 是绝对的。
  • 我可以从我的应用程序中完全删除所有 xml 配置吗?它不会降低我的应用程序的速度吗?我可以删除所有 XML 并为整个应用程序创建一个 WebConfig 吗?这个完整的教程是我在问题中提到的问候应用程序(Spring 的示例),我试过了。
  • 是的,您根本不需要 any xml。它绝对不会减慢应用程序的速度——它甚至可以加快它的速度,因为您的 XML 不需要“编译”成配置代码。您只需要确保 bootstrap your application 使用根配置类即可。
  • 蜘蛛鲍里斯,写一个关于删除所有 xml 的答案(包括 web.xml - 改为使用 WebInitializer)我会将其标记为答案。在此之后,我使用 websocket、sockjs 和 stomp 编写代码 - 一切正常。

标签: java spring-mvc stomp sockjs spring-websocket


【解决方案1】:

我到达了这个页面,并且 - 感谢Boris Accepted Answer 有动力重新考虑 java 方法,而不是导致 - /info=34424 和 404 错误的 xml 方法......哎呀失去了连接 - 我在我的项目中有 Spring 4.2,并且许多 SockJS Stomp 实现通常与 Spring Boot 实现配合良好。 This implementation from Baeldung 工作(对我来说没有从 Spring 4.2 更改为 5 或 Boot)。在使用他博客中提到的依赖项后,它仍然给我ClassNotFoundError。我添加了以下依赖项来修复它。

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.3.RELEASE</version>
    </dependency>

奇怪的是,Baeldung 的实现没有进行任何此类调用

flow/websocket/add/info?t=1540813753999

它的作用(发送和接收)如下。我只是粘贴它,以防精通这些库的人可以在这个论坛上进一步添加见解。

 >>> SEND
destination:/app/chat
content-length:38

{"from":"nicholas","text":"try again"}

<<< MESSAGE
destination:/topic/messages
content-type:application/json;charset=UTF-8
subscription:sub-0
message-id:m3p096zk-11
content-length:53

{"from":"nicholas","text":"try again","time":"13:46"}

【讨论】:

    【解决方案2】:

    首先,您已经为 app 设置了目的地前缀,因此您必须在请求 url 中添加“app”。例如如果我想请求“/ws”,我应该使用路径“/server/app/ws”创建 SockJS,你也可以使用 var socket = new SockJS("&lt;c:url value='/server/app/ws'/&gt;") 并且您知道“服务器”是您在 springmvc 上的项目名称。

    其次,必须在org.springframework.web.servlet.DispatcherServlet中添加路径'/app/*',以免web.xml中定义的拦截器拦截到前缀'/app'的路径。

    【讨论】:

      【解决方案3】:

      我遵循Boris The Spider 的建议,开始使用 Java 配置(AppConfig 和 WebInit 文件)而不是 XML 配置文件。当我完成迁移时 - 我尝试了 websockets - 它有效!我认为主要问题在于 WebSocket 的 XML 配置。

      【讨论】:

        【解决方案4】:

        我认为您的问题可能与this one 相同,并且可以应用其接受的答案。

        简而言之:检查您如何映射 DispatcherServlet。要使您的端点 URL 为 http://localhost:8080/ws DispatcherServlet 并且您的应用程序上下文根应设置为“/”。

        应该是这样的,在你的web.xml:

        <servlet>
          <servlet-name>WebSocketDispatcher</servlet-name>
          <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
          <load-on-startup>1</load-on-startup>
          <async-supported>true</async-supported>
        </servlet>
        <servlet-mapping>
          <servlet-name>WebSocketDispatcher</servlet-name>
          <url-pattern>/*</url-pattern>
        </servlet-mapping>
        

        这或者您需要在您的端点 URL 中包含上下文根和调度程序映射:

        http://<server>:<port>/<context-root>/<dispatcher-mapping>/ws
        

        希望对你有帮助。

        问候。

        海伦诺

        【讨论】:

        • 我现在不能检查这个,因为我的应用程序中没有更多的 xml 配置
        • @dikkini,只需从您的应用程序中删除 xml 配置即可解决问题,或者您是否还修复了 DispatcherServlet 映射和/或上下文根?我很好奇 WebInitializer 的解决方案。您不能自己发布作为答案吗?
        猜你喜欢
        • 2017-11-20
        • 2015-05-25
        • 2015-08-10
        • 1970-01-01
        • 2018-06-18
        • 1970-01-01
        • 2017-02-02
        • 2019-08-07
        • 2020-10-26
        相关资源
        最近更新 更多