Stomp over socket с помощью sockjs не может соединиться с Spring 4 WebSocket

Попытка использовать Spring 4 WebSocket с STOMP через сокет, используя sockjs. И я столкнулся с проблемой.

Моя конфигурация:

websocket.xml - часть весеннего контекста

<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.

3 ответа

Решение

Я следую совету Boris the Spider, и я начал использовать конфигурацию Java (файлы AppConfig и WebInit) вместо файлов конфигурации XML. Когда я закончил миграцию - я попробовал websockets - и это работает! Я думал, что основная проблема была в конфигурации XML для WebSocket.

Во-первых, вы установили префикс назначения в приложении, поэтому вы должны добавить "приложение" в URL вашего запроса. например, если я хочу запросить '/ ws', я должен создать SockJS с путем '/ server / app / ws', также вы можете кодировать с var socket = new SockJS("<c:url value='/server/app/ws'/>") и вы знаете, что "server" - это имя вашего проекта по сравнению с springmvc.

во-вторых, вы должны добавить путь '/app/*' в org.springframework.web.servlet.DispatcherServlet, чтобы избежать пути с префиксом '/ app', перехваченным перехватчиком, определенным в web.xml.

Я думаю, что ваша проблема может быть такой же, как и эта, и принятый ответ может применяться.

Вкратце: проверьте, как вы отобразили свой 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

Я надеюсь, что это может помочь вам.

С уважением.

Heleno

Я прибыл на эту страницу и - благодаря Boris the Spider принятый ответ был мотивирован пересмотреть подход java в отличие от подхода xml, который вызывал - /info=34424 с ошибкой 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 не делает таких вызовов.

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"}
Другие вопросы по тегам