Java 使用 sockjs 踩过套接字无法与 Spring 4 WebSocket 连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22481357/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 15:59:49  来源:igfitidea点击:

Stomp over socket using sockjs can't connect with Spring 4 WebSocket

javaspring-mvcstompsockjsspring-websocket

提问by dikkini

Trying to use Spring 4 WebSocket with STOMP over socket using sockjs. And i faced a problem.

尝试使用 sockjs 通过套接字使用 Spring 4 WebSocket 和 STOMP。我遇到了一个问题。

My configuration:

我的配置:

websocket.xml - part of spring context

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>       

Controller code:

控制器代码:

@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;
}

Client side:

客户端:

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);                                  
    });                                                           
});                                                               

Output:

输出:

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

What i do wrong?

我做错了什么?

I've found examples in google (TickerStocks or something like that, greeting applications (example of Spring)) and all of them give me the same error. I trying use WebSocket with handshake (without sockjs) - same result).

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

ADDITION INFORMATION:

添加信息:

Method public AjaxResponse hello();placed in IndexController on root context "/". So i can provide full path: http://localhost:8080/ws. To deploy tested tomcat7 and tomcat8.

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

采纳答案by dikkini

I follow Boris The Spideradvice and i started use Java Configuration (AppConfig and WebInit files) instead of XML configuration files. When i finished migration - i tried websockets - and it is works! I thought that the main problem was in XML configuration for WebSocket.

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

回答by helenov

I think your issue can be the same of this oneand its accepted answer can apply.

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

In short: check how you mapped your DispatcherServlet. For your endpoint URL to be http://localhost:8080/wsthe DispatcherServlet andyour application contexte root should be set as "/".

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

It should be something like this, in your web.xml:

它应该是这样的,在你的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>

This or you need to include context-root and dispatcher mapping in your end-point URL:

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

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

I hope it can help you.

我希望它能帮助你。

Regards.

问候。

Heleno

海伦诺

回答by Pacoson

firstly, you have set destination prefix with app, so you must add 'app' into your request url. e.g. if i wanted to request for '/ws', i should create SockJS with path '/server/app/ws', also you can code with var socket = new SockJS("<c:url value='/server/app/ws'/>")and you know the 'server' is your project name over springmvc.

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

secondly, you must add the path '/app/*' to org.springframework.web.servlet.DispatcherServlet so as to avoid the path with prefix '/app' intercepted by interceptor defined in web.xml.

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

回答by veritas

I arrived on this page and - thanks to BorisAccepted Answer was motivated to reconsider the java approach as opposed to the xml approach which was causing the - /info=34424 with 404 error...whoops lost connection - I have Spring 4.2 in my project and many SockJS Stomp implementations usually work well with Spring Boot implementations. This implementation from Baeldungworked(for me without changing from Spring 4.2 to 5 or Boot). After Using the dependencies mentioned in his blog, it still gave me ClassNotFoundError. I added the below dependency to fix it.

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

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

Baeldung's implementation curiously does not make any such calls

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

flow/websocket/add/info?t=1540813753999

What it does (on send and receive) is below. I am only pasting it in case people well-versed with these libraries can further add insights on this forum.

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

 >>> 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"}