Открыть сервисСервис

Протокол Mercure: технология и применение

Mercure — это открытый сетевой протокол, разработанный для передачи данных в реальном времени с сервера клиенту по технологии push-уведомлений. Протокол спроектирован как современная альтернатива WebSocket и Server-Sent Events (SSE), работающая поверх стандартного HTTP и использующая его инфраструктуру, включая прокси-серверы и системы аутентификации. Mercure был создан в 2018 году французским разработчиком Кевином Дюнгла и в первую очередь ориентирован на веб-приложения, построенные на платформе Symfony, хотя может применяться с любым языком программирования.

История и предпосылки создания

Появление Mercure связано с ограничениями существовавших на момент разработки технологий. WebSocket, хотя и обеспечивает полнодуплексную связь, требует поддержания долгоживущего соединения и не всегда корректно работает через корпоративные прокси и NAT. Server-Sent Events, в свою очередь, поддерживают только однонаправленную передачу и имеют ограничение на количество одновременных соединений с одним доменом в браузере. Протокол Mercure был представлен как решение, объединяющее простоту HTTP с возможностью мгновенной доставки событий. Первая стабильная версия спецификации была опубликована в 2020 году, после чего протокол был включён в экосистему фреймворка Symfony в качестве компонента Mercure Component.

Архитектура и принцип работы

Mercure использует модель «публикация-подписка» (pub/sub). Взаимодействие строится вокруг трёх основных участников: клиента, сервера публикации и концентратора (hub). Концентратор выступает центральным узлом, который принимает сообщения от серверов приложений и рассылает их подписанным клиентам.

Клиент устанавливает долгоживущее HTTP-соединение с концентратором с помощью стандартного механизма EventSource (Server-Sent Events). После установления соединения клиент отправляет запрос на подписку, указывая интересующие его темы (topics). Темы представляют собой URI, которые могут описывать конкретные ресурсы, например /books/123 или https://example.com/users/456`.

Сервер приложения, желающий уведомить клиентов об изменении данных, отправляет POST-запрос на конечную точку концентратора. В теле запроса передаётся содержимое уведомления и список тем, к которым это уведомление относится. Концентратор проверяет подлинность запроса и пересылает уведомление всем клиентам, подписанным на указанные темы.

Отличия от WebSocket и SSE

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

Технические характеристики

Протокол определяет два типа конечных точек: точка подписки (для клиентов) и точка публикации (для серверов). Точка подписки доступна через GET-запрос с параметрами topic и Last-Event-ID для восстановления пропущенных событий. Точка публикации принимает POST-запросы с данными формы или JSON.

Аутентификация в Mercure построена на механизме подписанных токенов JWT. Для публикации сообщений сервер приложения должен обладать токеном с правом publish. Для подписки клиент может предоставить токен с правом subscribe, ограничивающий доступ к определённым темам. Если токен не передан, подписка разрешена только на публичные темы, объявленные в конфигурации концентратора.

Формат передаваемых данных основан на спецификации SSE: каждое событие содержит поле data, при необходимости дополняется полями id, event и retry. Mercure добавляет собственные расширения, такие как указание типа контента и приватность сообщения. Приватные сообщения (передаваемые с флагом private) доставляются только клиентам, прошедшим аутентификацию и имеющим право на подписку на соответствующую тему.

Применение и экосистема

Основная область применения Mercure — веб-приложения, требующие мгновенного обновления интерфейса без перезагрузки страницы. Типичные сценарии включают:

  • уведомления о новых сообщениях в чатах и системах обмена сообщениями;
  • обновление корзин интернет-магазинов и статусов заказов;
  • совместное редактирование документов;
  • трансляция биржевых котировок и спортивных результатов;
  • синхронизация состояния между несколькими вкладками браузера.

Протокол наиболее плотно интегрирован в экосистему Symfony. Начиная с версии 5.2 фреймворк включает официальную поддержку Mercure, предоставляя разработчикам готовые классы для отправки обновлений из контроллеров и использования асинхронных компонентов Messenger. Однако реализация клиента доступна для JavaScript, а также для серверных языков через сторонние библиотеки, включая PHP, Go и Python.

Инфраструктурные решения

Для производственного использования предлагается готовый концентратор, написанный на языке Go. Он распространяется как отдельный исполняемый файл и может быть развёрнут на любом сервере. Концентратор поддерживает горизонтальное масштабирование через Redis или кластерную шину сообщений. Альтернативные реализации концентратора созданы на PHP и Node.js, однако официальная Go-версия остаётся эталонной.

Ограничения и недостатки

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

Браузерная поддержка ограничена реализацией EventSource: все современные браузеры поддерживают технологию, однако Internet Explorer требует полифилла. При использовании HTTP/1.1 действует ограничение на количество одновременных соединений, что может потребовать применения HTTP/2 на уровне обратного прокси.

Сравнение с альтернативами

Выбор между Mercure, WebSocket и SSE зависит от конкретной задачи. WebSocket целесообразно применять для двустороннего обмена данными, например в онлайн-играх или редакторах кода. SSE подходит для простых сценариев доставки уведомлений с одного сервера. Mercure занимает промежуточное положение, предлагая удобный механизм публикации из любого компонента приложения и встроенную поддержку аутентификации и приватных каналов.

Источники

  • Спецификация протокола Mercure (draft-version, официальный репозиторий проекта).
  • Документация Symfony Mercure Component, Symfony 5.2–6.x.
  • Официальная документация концентратора Mercure (mercure.rocks).
  • Статья К. Дюнгла «Introducing Mercure» (2018).
Заметили ошибку или не согласны с информацией в статье? Напишите нам support@bfometr.ru