Angular 7 + Java Spring — Websocket возвращает 404

Я пытаюсь использовать Spring 4 Websocket и Angular 7 через библиотеку @stomp/stompjs и SockJS, однако он продолжает возвращать 404 не найдено, и в результате соединение с веб-сокетом закрывается.

Мой код конфигурации в Spring:

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.annotation.EnableScheduling;
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 SocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/batch-socket").withSockJS();
    }

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/socketio/");
    }   
} 

SocketHandlerService.java для отправки шаблона сообщения

@Service
public class SocketHandlerService  extends AbsLogger<SocketHandlerService> implements ApplicationListener<BrokerAvailabilityEvent> {

   private final MessageSendingOperations<String> messagingTemplate;

   @Autowired
   public SocketHandlerService(MessageSendingOperations<String> messagingTemplate) {
       this.messagingTemplate = messagingTemplate;      
   }

   public SocketDetails sendRestMessage() {
         ...some code...
                        this.messagingTemplate.convertAndSend("/socketio/batchupdate", data);
         ...some code...            
     } 
   }

Angular socket.service.ts для обработки веб-сокетов на стороне клиента

  init() {
    let connectionUrl = this.baseUrl + "batch-socket";

    return new Promise((resolve, reject) => {
        let config = new StompConfig();
        config.heartbeatOutgoing = 5000;
        config.heartbeatIncoming = 5000;
        config.webSocketFactory = function () {
          return new SockJS(connectionUrl, null, { transports: ['websocket' , 'xhr-streaming','xhr-polling' ] });
        }
        config.debug = function (str) {
          console.log("@socketDebug: " + str)
        }
      this.client = new Client();
      this.client.configure(config);

      enableLogs && console.log(this.client);
      console.log("@socketSvc: starting connection...");

      const _this = this;
      this.client.onConnect = function (frame) {
        console.log("@socketSvc: connection established.");
        console.log(frame);
        _this.state = new BehaviorSubject<any>(SocketClientState.ATTEMPTING);
        _this.state.next(SocketClientState.CONNECTED);
        resolve(frame.headers['user-name']);
      }

      this.client.onWebSocketClose = function (msg){
        console.log("@socketSvc: connection closed.");
        console.log(msg);
      }

      this.client.activate();
    });

  }

Я проверил, что URL-адреса конечных точек совпадают, и что домен для сервера и клиента, который используется, также одинаков. Однако при развертывании появляется следующий вывод консоли:

POST https://exampleWebsite.com/Portal/batch-socket/718/ky4ln33y/xhr_send?t=1576031555275 404 (Not Found)
                                                           main.7459b10fe35bab2c58d4.js:179295 

@socketDebug: Connection closed to https://exampleWebsite.com/Portal/batch-socket 
                                                           main.7459b10fe35bab2c58d4.js:179310 

@socketSvc: connection closed.                             main.7459b10fe35bab2c58d4.js:179311 

i {type: "close", bubbles: false, cancelable: false, timeStamp: 1576031555344, wasClean: false, …}bubbles: falsecancelable: falsecode: 1006reason: "Sending error: Error: http status 404"timeStamp: 1576031555344type: "close" wasClean: false__proto__: r
                                                           main.7459b10fe35bab2c58d4.js:179295 

@socketDebug: STOMP: scheduling reconnection in 5000ms

Я также просмотрел инструменты разработчика для веб-браузера, чтобы проверить сеть: вкладка сети

Могу ли я узнать, в чем проблема для создания тесного соединения? Иногда требуется несколько попыток, прежде чем веб-сокет будет успешно установлен. В других случаях для успешного соединения требуется целая вечность.


person Shanny    schedule 11.12.2019    source источник
comment
дайте нам больше логов со стороны сервера   -  person Yati Sawhney    schedule 11.12.2019


Ответы (1)


Следующий код работает для меня!!

@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("/batch-socket");
         registry.addEndpoint("/batch-socket").withSockJS();
    }
}

Контроллер обработки сообщений:

@MessageMapping("/batch-socket")
@SendTo("/topic/messages")
public OutputMessage send(Message message) throws Exception {
    String time = new SimpleDateFormat("HH:mm").format(new Date());
    return new OutputMessage(message.getFrom(), message.getText(), time);
}

Полезная нагрузка:

public class Message {

    private String from;
    private String text;

    // getters and setters
}
person Yati Sawhney    schedule 11.12.2019
comment
Спасибо, скоро попробую! Могу ли я узнать, почему есть дублированные конечные точки и одна с withSockJS()? И влияет ли добавление префикса к брокеру на общее подключение к веб-сокету? - person Shanny; 11.12.2019
comment
Ах!!! вы можете просто игнорировать registry.addEndpoint("/batch-socket");, если используете только sockjs. но всегда хорошо иметь резервную конечную точку, которую можно использовать для создания соединений WebSocket. - person Yati Sawhney; 11.12.2019
comment
Спасибо за быстрый ответ! Я смогу развернуть свой код только завтра, надеюсь, он будет исправлен! :) - person Shanny; 11.12.2019