Найти тему
Nuances of programming

Знакомство с AWS WebSocket

Источник: Nuances of Programming

Что такое WebSocket?

Если просто, то WebSocket  —  это прямая линия связи между клиентом и сервером. Разберем на примере Twitter. Соединение WebSocket  —  это двухсторонняя связь между мобильным приложением (или сайтом) и серверами Twitter.

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

Необходимы ли уведомления? Технически нет, но они улучшают пользовательский опыт и удовольствие от работы с продуктом.

Начало работы с AWS WebSockets

WebSocket в системе AWS  —  это ресурс API Gateway v2. Он поддерживает двухстороннюю связь между клиентом и сервером, в том числе позволяя настраивать собственные маршруты.

В этой статье мы разберем пример WebSocket, написанного с помощью шаблона SAM. Этот шаблон я выбрал за то, что он позволяет легко развертывать бессерверные приложения прямо в AWS без использования сторонних сервисов.

Для начала перейдите в репозиторий примера и следуйте командам развертывания. Если AWS CLI и SAM CLI у вас уже установлены, то на подготовку всех компонентов у вас уйдет не более 5 минут.

Маршруты WebSocket

Как и в любом API, в WebSocket есть активирующие функциональность маршруты. При этом у WebSocket API их должно быть не менее двух:

  • $connect  —  указывает, что происходит, когда от клиента к серверу устанавливается новая прямая линия/соединение;
  • $disconnect  —  указывает, что происходит, когда прямая линия/соединение между клиентом и сервером удаляется.

В нашем примере присутствуют лямбда-функции, которые выполняются в каждой из этих конечных точек. Мы сохраняем важную информацию о соединениях, такую как connectionId, ipAddress и connectedAt, чтобы иметь метаданные о том, кто устанавливает соединения. Этот процесс следует базовому паттерну API Gateway -> Lambda -> DynamoDB, который выступает основополагающим строительным блоком в любой бессерверной разработке.

В развернутом нами примере WebSocket API есть два дополнительных маршрута.

  • subscribe — подписывается на получение push-уведомлений при обновлении конкретной сущности;
  • unsubscribe — отписывается от push-уведомлений от конкретной сущности.

Большинство из встречающихся в интернете готовых примеров WebSocket используются для транслируемых уведомлений (англ.), которые рассылаются по каждому текущему подключению. В более реалистичном сценарии человек хотел бы получать обновления, когда изменяется его пользователь или сущность, с которой он работает. Поэтому наш пример предоставляет способ сузить отправку push-уведомлений для конкретных сущностей по принципу отдельных соединений.

Проверка подключения

Для проверки WebSocket можно получить вывод WebsocketUri из развертываемой SAM и подключитьcя к ней в Postman. Postman  — это приложение, созданное для всесторонней работы с API, включая подключение к WebSocket.

Для подключения к новому WebSocket в Postman выполните следующее:

  1. Выберите New -> WebSocket Request
  2. В адресное поле введите маршрут, полученный из вывода развертываемой вами SAM.
  3. Кликните по вкладке Headers и добавьте заголовок Sec-WebSocket-Protocol со значением websocket.
  4. Нажмите Connect.
После подключения к WebSocket в Postman
После подключения к WebSocket в Postman

Когда мы хотим подписаться или отписаться от обновлений, необходимо добавить полезную нагрузку, описывающую соответствующий этому маршрут. В случае с созданным нами API нужный маршрут описывается свойством action.

Опять же, свойство action сообщает API, каким маршрутом следовать, а свойство entityId представляет параметр, который мы передаем в лямбда-функцию подписки, реализованную в примере проекта.

Теперь, когда мы подключились к WebSocket, добавьте в Postman следующее сообщение и нажмите кнопку Send. Оно достигнет конечной точки и сохранит подписку:

Добавление подписки на обновление сущности
Добавление подписки на обновление сущности

Установив подключение и подписку, можно переходить к тестированию push-уведомлений.

Отправка push-уведомлений

Первое, что нам нужно — это заглянуть в DynamoDB и проверить подключение вместе с сохраненной подпиской. Если перейдете в таблицу websocket в консоли DynamoDB, то увидите там две записи: connection и subscription.

Подключение и подписка WebSocket в DynamoDB
Подключение и подписка WebSocket в DynamoDB

Теперь, когда мы убедились в установке подключения и подписки, можно перейти к консоли EventBridge, чтобы добавить сообщение вручную.

В примере проекта, который мы передали в AWS, push-уведомления активируются событием EventBridge. Это событие добавляется в очередь SQS, которая обрабатывается лямбдой. Лямбда-функция ищет все подписки для entityId, представленные в событии, и отправляет push-уведомление всем подписчикам.

Для того, чтобы отправить событие вручную, кликните кнопку Send Events в консоли EventBridge и добавьте следующие указанные в скриншоте детали:

Детали события EventBridge
Детали события EventBridge

После запустится процесс, и подключению в Postman будет отправлено push-уведомление.

Если переключиться обратно к Postman, то мы увидим полученное сообщение Hello world.

Push-уведомление сработало!
Push-уведомление сработало!

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

Дальнейшие шаги

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

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

Можете смело использовать приведенный код на свое усмотрение, хотя он еще не вполне пригоден для продакшена  —  не хватает обработки ошибок и механизма повтора  —  но основное уже готово. Его задачей было продемонстрировать все подвижные элементы, которые участвуют в AWS WebSocket API.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Allen Helton: Introduction to AWS Websockets