Что такое Server-Sent Events (SSE)?java-80

Server-Sent Events (SSE) — это технология, позволяющая серверу отправлять события клиенту через HTTP-соединение. В отличие от WebSocket, SSE является односторонним (сервер → клиент) и использует стандартный HTTP-протокол. Это делает SSE идеальным решением для сценариев, где серверу нужно отправлять данные клиенту в реальном времени, например, для уведомлений, лент новостей или обновлений статуса.

Основные особенности SSE

1. Односторонняя связь

SSE позволяет серверу отправлять данные клиенту, но не наоборот. Это отличает SSE от WebSocket, который поддерживает двустороннюю связь.

2. Использование HTTP

SSE работает поверх HTTP, что делает его совместимым с существующей инфраструктурой, включая прокси-серверы и брандмауэры.

3. Автоматическое восстановление соединения

Если соединение разрывается, клиент автоматически пытается восстановить его, отправляя последний полученный идентификатор события (last-event-id).

4. Простота реализации

SSE легко реализовать как на стороне сервера, так и на стороне клиента, используя стандартные инструменты.

Как работает SSE

1. Установление соединения

Клиент отправляет HTTP-запрос на сервер с заголовком Accept: text/event-stream. Сервер отвечает с заголовком Content-Type: text/event-stream и начинает отправлять события.

Пример HTTP-запроса:

GET /events HTTP/1.1
Host: example.com
Accept: text/event-stream

Пример ответа сервера:

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

data: {"message": "Hello, World!"}

data: {"message": "Another message"}

2. Формат событий

События отправляются в текстовом формате, где каждое событие состоит из одной или нескольких строк, начинающихся с ключевых слов:

  • data: — содержимое события.
  • id: — уникальный идентификатор события.
  • event: — тип события (необязательно).
  • retry: — время в миллисекундах, через которое клиент должен попытаться восстановить соединение (необязательно).

Пример события:

id: 1
event: message
data: {"text": "Hello, World!"}

3. Закрытие соединения

Соединение остается открытым, пока сервер или клиент не закроют его явно.

Пример реализации SSE на Java с использованием Spring

Настройка SSE на сервере

@RestController
public class SseController {

    @GetMapping(path = "/events", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> streamEvents() {
        return Flux.interval(Duration.ofSeconds(1))
                  .map(sequence -> ServerSentEvent.builder("Event #" + sequence)
                                                  .id(String.valueOf(sequence))
                                                  .build());
    }
}

В этом примере:

  • Метод streamEvents() возвращает поток событий (Flux<ServerSentEvent<String>>).
  • Каждую секунду генерируется новое событие с текстом "Event #" и уникальным идентификатором.

Клиентская часть

const eventSource = new EventSource('/events');

eventSource.onmessage = function(event) {
    console.log("Received event: " + event.data);
};

eventSource.onerror = function(error) {
    console.error("EventSource failed: " + error);
};

В этом примере:

  • Создается объект EventSource, который подключается к эндпоинту /events.
  • События обрабатываются в функции onmessage.
  • Ошибки обрабатываются в функции onerror.

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

  • Простота: Легко реализовать и использовать.
  • Совместимость: Работает поверх HTTP, что делает его совместимым с большинством инфраструктур.
  • Автоматическое восстановление: Клиент автоматически восстанавливает соединение при разрыве.

Резюмируем

Server-Sent Events (SSE) — это технология, позволяющая серверу отправлять события клиенту в реальном времени через HTTP. Она идеально подходит для сценариев, где требуется односторонняя связь, таких как уведомления или обновления статуса. SSE легко реализовать с использованием современных фреймворков, таких как Spring, и он отлично интегрируется с клиентскими приложениями через стандартный JavaScript API.