Почему мой клиент React с Next.js не получает сообщения, отправляемые WebSocket на бэкенде Spring Boot?

Вопрос или проблема

Я пытаюсь реализовать систему WebSocket. На сервере я правильно настроил WebSocket и сервис, который отправляет сообщения. Клиент на React без проблем подключается к WebSocket, но проблема в том, что он не может перехватить сообщения, отправленные сервером.

Вот конфигурация WebSocket на сервере Java Spring Boot:

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic", "/queue");
        config.setApplicationDestinationPrefixes("/app");
        config.setUserDestinationPrefix("/user");
    }
    
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/notifications")
                .setAllowedOrigins("http://localhost:3000") // Разрешить источник фронтенда
                .withSockJS();
    }
}

@Service
public class NotificationService {

    private final SimpMessagingTemplate messagingTemplate;
    
    @Autowired
    public NotificationService(SimpMessagingTemplate messagingTemplate) {
        this.rabbitTemplate = rabbitTemplate;
        this.messagingTemplate = messagingTemplate;
    }
    
    public void sendWelcomeNotification(UserEntity loggedInUser) {
        // Данные уведомления
        String message = "Добро пожаловать в HydroLife, " + loggedInUser.getName() + "!";
        String sender = "HydroLife";
        LocalDateTime timestamp = LocalDateTime.now();
        String profileImage = "/images/Logo3.png";
        var notification = new NotificationDTO(sender, message, timestamp, profileImage);
    
        /// Отправка уведомления через WebSocket на фронтенд
        // Конвертация и отправка по конкретному пользователю
        messagingTemplate.convertAndSendToUser(
                loggedInUser.getEmail(),
                "/queue/notifications",
                notification
        );
    }
}

На фронтенде я использую клиент WebSocket в React с Next.js для подключения к серверу, но он не захватывает сообщения. Вот код клиента:

useEffect(() =\> {
    const socket = new SockJS('http://localhost:8080/notifications');
    const stompClient = new Client({
    onConnect: () =\> {
    console.log('Подключено к WebSocket');
    
        stompClient.subscribe('/user/queue/notifications', (message) => {
          const notificationData = JSON.parse(message.body);
          setNotification(notificationData);
          console.log('Новое уведомление получено:', notificationData);
        });
      },
    });
    
    stompClient.activate();
    
    return () => {
      if (stompClient) {
        stompClient.deactivate();
        console.log('Отключено от WebSocket');
      }
    };

}, []);

Соединение WebSocket устанавливается успешно (клиент подключается к серверу), но клиент не может перехватить или отобразить сообщения, отправленные сервером. console.log внутри stompClient.subscribe никогда не срабатывает, хотя бэкенд-сервис отправляет сообщения в тему.

Я уже проверил, отправляет ли сервер сообщения, и, похоже, все работает правильно. Почему мой React-клиент с Next.js не получает сообщения от WebSocket на бэкенде Spring Boot? Есть ли что-то, что я мог бы упустить, или какая-то неправильная настройка в коммуникации WebSocket?

Ответ или решение

Проблема с тем, что ваш React-клиент на Next.js не получает сообщения от веб-сокета Spring Boot, может быть связана с несколькими аспектами настройки веб-сокетов и подписки на сообщения. Давайте рассмотрим основные возможные причины и решения.

Проверьте настройки сервера Spring Boot

  1. Настройка конечной точки и CORS:
    Вы уже правильно настроили конечную точку /notifications в вашем сервере. Убедитесь, что CORS (Cross-Origin Resource Sharing) настроен правильно для вашего клиента Next.js, который работает на http://localhost:3000. Вы можете добавить дополнительную конфигурацию CORS, если это необходимо, но обычно, настроив setAllowedOrigins(), этого должно быть достаточно.

  2. Убедитесь, что сообщения отправляются на правильный адрес:
    У вас есть вызов convertAndSendToUser() в сервисе NotificationService, который отправляет сообщения на /queue/notifications. Обратите внимание, что это потребует идентифицировать пользователя, и используется его email в качестве имени пользователя. Убедитесь, что процесс аутентификации и идентификации пользователя работает правильно и что email, который используется в sendWelcomeNotification, совпадает с тем, на который подписан клиент.

Проверьте клиентскую часть

  1. Синтаксическая ошибка при использовании SockJS и Stomp:
    Убедитесь, что вы правильно импортируете и используете библиотеки для поддержки SockJS и STOMP. Примерный импорт должен выглядеть так:

    import { Client } from '@stomp/stompjs';
    import SockJS from 'sockjs-client';
  2. Правильная подписка на сообщения:
    Вы находитесь на правильном пути, когда подписываетесь на /user/queue/notifications. Убедитесь, что в endpoints на сервере также соблюћается эта структура. Ваш клиент должен ожидать сообщения именно с этого пути.

  3. Проверьте выполнение коллбека:
    Убедитесь, что коллбек для onConnect вызывается правильно, и что stompClient.subscribe вызывается внутри этого коллбека. Возможно, стоит добавить отладочные сообщения перед подпиской и внутри неё:

    onConnect: () => {
       console.log('Connected to WebSocket');
       stompClient.subscribe('/user/queue/notifications', (message) => {
           const notificationData = JSON.parse(message.body);
           setNotification(notificationData);
           console.log('New notification received:', notificationData);
       }, { subscriberId: 'my-subscription' });
    }

Проверка отладочной информации

  1. Логи на сервере:
    Проверьте логи вашего сервера на наличие ошибок, которые могут указывать на проблемы с отправкой сообщения.

  2. Инспектор сети (Network Inspector):
    В инструментах разработчика вашего браузера проверьте сеть на наличие установленных соединений и сообщений, чтобы увидеть, отправляются ли любые сообщения.

Дополнительные советы

  • Убедитесь, что серверный процесс правильно настроен для поддержки и отправки пользовательских сообщений.
  • Ваша библиотека STOMP должна быть совместима с использованием SockJS. Убедитесь, что версии библиотек актуальны.
  • Правильность подключения и аутентификации пользователя имеет ключевое значение: если ваш email не соответствует идентификатору, роли могут не позволить вашему клиенту получать уведомления.

Следуя этим рекомендациям, вы сможете диагностировать и решить проблему, из-за которой ваш React-клиент не получает сообщения от веб-сокета на бекенде Spring Boot. Если проблема не решится, возможно, стоит рассмотреть возможность настройки более глубокой отладки или добавления функциональности для обработки ошибок.

Оцените материал
Добавить комментарий

Капча загружается...