Server Sent Events в Java EE

Необходимость коммуницировать клиенту и серверу существует не только в Java EE-приложениях, но и в любых других веб-приложениях. Как известно, для этих целей используются различные подходы, например, поллинг. При поллинге клиент периодически опрашивает сервер, отправляя клиентский запрос, а тот в свою очередь формирует ответ на него.

То есть для поддержки актуального состояния данных, клиент должен постоянно опрашивать сервер для получения обновлённых данных. Такой подход не всегда удобен, так как требует дополнительных накладных расходов и действий со стороны клиента (если обновление данных на сервере не произошло, сеть нагружается впустую). Устранить некоторые недостатки поллинга помогают его разновидности, тот же Long polling.

Мейнстримной технологией отправки уведомлений от клиента к серверу и обратно на сегодняшний день является технология WebSocket. Веб-сокеты впервые были представлены в Java EE 7-й редакции. Они позволяют организовывать двунаправленную (полнодуплексную) коммуникацию между клиентом и сервером, используя в качестве основы протокол TCP. При этом тот самый протокол НТТР, который применялся для поллинга, используется единожды для осуществления так называемого «рукопожатия» (handshake), которое позволяет клиенту и серверу установить соединение между собой. В последующем обмен информацией между взаимодействующими сторонами происходит посредством более высокоуровневого протокола ws/wss.

Чтобы поток обмена был двунаправленным, у клиента и сервера есть все необходимые средства для передачи данных, и вне зависимости от того, кто будет инициирующей стороной. Если клиент хочет синхронизировать состояние с сервером, он отправляет соответствующие данные, а если серверу есть, что сообщить клиенту, — он посылает порцию необходимых данных, зачастую в виде дельты от первоначального объёма информации.

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

Вышеперечисленные подходы применяются довольно широко. Однако в некоторых случаях решить задачи, с которыми может столкнуться современный разработчик, дополнительно помогает ещё один механизм – Server Sent Events.

Особенности работы Server Sent Events

Начиная с HTML5, появилась возможность однонаправленной коммуникации от сервера к клиенту, генерируя события, приводящие к обновлению данных на клиенте. Этот подход позволяет расширять возможности клиента и актуализировать данные без лишних обращений со стороны клиента, например, получая уведомления о различных событиях.

Данная технология не обошла стороной Java EE и используется в ней, начиная с восьмой версии. Прежде всего данный подход нашл отражение в двух распространённых технологиях Java EE: сервлеты и JAX-RS.

Говоря о Server Sent Events с практической точки зрения, можно привести следующий пример REST-сервиса:

@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public void news(@Context SseEventSink eventSink, @Context Sse sse) {
    try(SseEventSink sink = eventSink){
        sink.send(sse.newEvent("data"));
        sink.send(sse.newEvent("MyEventName","more data"));

        OutboundSseEvent event = sse.newEventBuilder().
            id("EventId").
            name("EventName").
            data("Data").
            reconnectDelay(10000).
            comment("Anything i wanna comment here!").
            build();

        sink.send(event);

    }
}

Вот, собственно, и всё

Получить более подробную информацию вы всегда можете на интерактивных занятиях курса «Разработчик Java Enterprise».

Интересуют нюансы работы Server Sent Events? Задавайте вопросы в комментариях!