Backend
October 12, 2023

Работа с WebSockets в Spring

Наверное, ты слышал про HTTP - основной протокол, который используется в интернете. Но он не очень подходит, если надо быстро отправлять данные туда-сюда. Вот тут и пригодятся WebSockets! Они позволяют установить постоянное соединение между браузером и сервером для молниеносной передачи данных.

К примеру, в многопользовательских играх или чатах очень важно, чтобы сообщения доходили мгновенно. И тут WebSockets - просто находка!

Основы WebSockets

WebSocket - это протокол, который работает поверх HTTP. Он позволяет устанавливать двустороннее постоянное соединение между клиентом (браузером) и сервером.

В отличие от HTTP, где клиент делает запрос, а сервер отвечает, в WebSockets связь постоянная - и клиент, и сервер могут посылать данные в любой момент. Не надо каждый раз запрашивать обновления, как в HTTP.

Преимущества WebSockets

Главное преимущество WebSockets - скорость! Данные передаются практически мгновенно. Нет необходимости постоянно опрашивать сервер на предмет обновлений.

Это сильно экономит трафик и серверные ресурсы. Представь чат с 1000 участников - без WebSockets серверу пришлось бы обрабатывать 1000 запросов каждую секунду! А с WebSockets данные отправляются сразу на все подключенные устройства.

Spring и WebSockets

Теперь давай посмотрим, как добавить WebSockets в Spring приложение. Spring - популярный фреймворк для Java, если ты не знал.

В Spring есть встроенная библиотека Spring WebSocket, которая сильно упрощает работу с WebSockets. Нам нужно всего лишь подключить необходимые зависимости в проект - и можно писать код!

Как создать WebSocket Endpoint

WebSocket endpoint - это как конечная точка, через которую клиент и сервер обмениваются данными. Чтобы создать его в Spring, нужно:

  1. Создать класс и пометить его аннотацией @ServerEndpoint.
  2. Добавить методы с аннотацией @OnOpen - будет вызываться при установке соединения.
  3. Добавить метод с @OnMessage - для получения сообщений.
  4. Добавить метод с @OnClose - вызывается при закрытии соединения.

Вот пример кода:

@ServerEndpoint("/chat") 
public class ChatEndpoint {

  @OnOpen
  public void onOpen(){
    //Initialization
  }
  
  @OnMessage
  public void onMessage(Session session, String msg) {
    //Handle message
  }

  @OnClose
  public void onClose(){
    //Cleanup
  }
  
}

Теперь этот endpoint будет обрабатывать все WebSocket-соединения по адресу /chat.

Обмен сообщениями

После установки соединения мы можем отправлять и получать сообщения.

Для отправки используем метод session.getBasicRemote().sendText(msg).

A для получения - аннотируем метод @OnMessage и пишем логику обработки в нем.

Например, для чата:

  @OnMessage
  public void onMessage(Session session, String msg) {
    
    //Отправить сообщение всем подключенным клиентам
    for(Session client : clients){
      client.getBasicRemote().sendText(msg);
    }
    
  }

Работа с событиями в реальном времени

Одно из главных применений WebSockets - работа с событиями в режиме реального времени. К примеру, уведомления, трекинг активности пользователей, биржевые котировки и т.д.

Мы можем добавить подписку на события в наш endpoint:

  @OnOpen
  public void onOpen(Session session){
    //Подписать клиента на события
  }
  
  @OnEvent
  public void handleEvent(Session session, Event event){
    //Отправить событие подписавшимся клиентам
  }

Теперь при возникновении события метод handleEvent сработает и отправит данные всем подписчикам.

Обработка ошибок

При работе с WebSockets могут возникать ошибки - соединение оборвалось, не удалось декодировать сообщение и т.д.

Для обработки ошибок в Spring есть аннотация @OnError:

  @OnError
  public void onError(Session session, Throwable error){
    //Вывести сообщение об ошибке в лог
  }

Важно правильно обрабатывать ошибки, чтобы приложение было стабильным.

Заключение

Как видишь, WebSockets - очень полезная технология для создания быстрых и масштабируемых приложений. С помощью Spring можно легко добавить поддержку WebSockets и использовать все их преимущества.