@exe01

Какие есть подходы для взаимодействия по websockets?

Решил реализовать приложение реального времени полностью построенном на websockets. До этого был опыт работы с RESTapi, RPC over HTTP и библиотекой SocketIO. Если подходы RESTapi и RPC мне понятны и по ним есть кучу примеров с описанием достоинств и недостатков, то по websockets информации очень мало.
Знаю что существует библиотека SocketIO, которая позволяет как отправлять сообщения сервер->клиент или клиент->сервер, так и имеет возможность реализовать что-то на подобии request response (и все это может работать на websockets). Но я хочу реализовать все без этой либы.
Так какие есть подходы для взаимодействия по websockets?
  • Вопрос задан
  • 99 просмотров
Пригласить эксперта
Ответы на вопрос 1
OCTAGRAM
@OCTAGRAM
Ну как, разрабатываете протокол и воплощаете.

Протоколы, которые я делал, устроены примерно по такой схеме:

На каналы WebSocket ставится мультиплексор в оба направления. Мультиплексор различает новые запросы и ответы на старые.

Инициатор нового запроса генерирует уникальный ключ, по которому он собирается ждать ответ, и шлёт ключ с запросом. Для обработки новых запросов запускается новая асинхронная функция (горутина). Когда она закончила, она отправляет результат с указанным ключом.

Для получения ответов мультиплексор на стороне JS хранит изнанки обещаний (кортеж из замыканий resolve и reject) в карте по ключам запроса. При получении мультиплексором ответа из карты по ключу извлекается такая изнанка, и вызывается resolve или reject.

В JavaScript, таким образом, асинхронная функция может сделать await new Promise, с функцией, которая сохранит аргументы-изнанку resolve&reject в карте мультиплексирования, отправит запрос, и такое выражение в асинхронной (async) функции вернёт сразу ответ или исключение. Аналогично делается в Go.

В итоге получается двусторонний RPC, с обоих сторон вызываемый в синхронном стиле. Придумываете, как сериализовать/распечатывать аргументы, и делаете.

На стороне Go я бы в качестве аналога кортежа из замыканий resolve и reject использовал монитор. Монитор защищает двух- или одноэлементный объект, в котором одна ячейка выделена для будущего результата, а вторая для ошибки, или они совмещены. Такие объекты с мониторами складываются в карту с ключами. Есть способ при получении ответа от JS положить значение или ошибку в монитор так, чтоб сработала условная переменная. Условная переменная срабатывает, когда под защитой монитора что-то появляется. Горутины, которые хотят от JS ответ, кладут объект с монитором в карту, отправляют по WS запрос и повисают на ожидании условной переменной.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы