Масштабируемый чат-сервер в Clojure. Проблемы с наличием и приходом сообщения ч / б переподключения

Я пытаюсь построить масштабируемый чат-сервер в Clojure. Я использую http-kit, compojure и redis pub/sub для связи между различными узлами (подход разветвления). Сервер будет использовать веб-сокеты для подключения ч / б клиент-сервер с переходом на длительный опрос. Один пользователь может иметь несколько подключений к чату с одним подключением на вкладках в браузере, и сообщение должно быть доставлено всем подключениям.

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

{:userid1 [{:socketuuid "random uuid#1 for uerid1" :socket "channel#1 for userid1"}
          {:socketuuid "random uuid#2" :socket "channel#2"}]
:userid2 [{:socketuuid "random uuid#1 for userid2" :socket "channel#1 for userid2}]}

сообщение помещено в общий маршрут для веб-сокетов и длинных каналов опроса, структура сообщения выглядит следующим образом

{:from "userid1" :to "userid2" :message "message content"}

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

Поэтому проблема, с которой я сталкиваюсь, заключается в том, как правильно реализовать присутствие. По сути, http-kit отправляет вам состояние, когда канал отключается. Состояние может быть "закрыто на сервере" или "закрыто на клиенте", в то время как я могу обрабатывать разъединения с сервером (клиент будет переподключаться автоматически), но у меня возникает проблема, когда отключение происходит со стороны клиента, например. пользователь переходит на другую страницу и подключится через несколько секунд. Как я могу решить, что пользователь отключился, когда клиент отключился. Кроме того, меня беспокоит повторное подключение ч / б сообщения в режиме длинного опроса (мой длительный тайм-аут опроса составляет 30 секунд).

Также, пожалуйста, предложите хороший механизм присутствия для вышеуказанной архитектуры. Благодарю.

Пожалуйста, прокомментируйте, если вам нужно больше информации. Спасибо

Редактировать № 1:

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

Мое текущее решение -> В настоящее время я поддерживаю глобальный счет и последнюю подключенную временную метку для подключенных каналов определенного идентификатора пользователя, а когда пользователь отключается, счетчик уменьшается, и устанавливается таймаут на 10 секунд, который проверяет, есть ли у пользователя снова подключен (т. е. последний подключенный штамп имеет возраст 10 секунд, а счетчик по-прежнему равен нулю), если нет, то пользователь, как говорят, перешел в автономный режим, порекомендуете ли вы это решение, если нет, то или любые улучшения или более эффективные методы приветствуются. Также, пожалуйста, обратите внимание, что я использую таймер / запланированное задание в http-kit, будут ли эти задержки значительными эффектами производительности?

1 ответ

Здесь есть два разных случая со стороны клиента.

  1. Длинный опрос. Я не вижу, как это проблема, если окно клиента закрывается, больше не будет опроса. На одного клиента меньше, который запрашивает данные.
  2. WebSockets. В протоколе доступен метод close. Клиент должен отправить уведомление, если вы правильно его внедрили. Смотрите здесь: Например, корректное закрытие WebSocket (HTML5, Javascript).

Это отвечает на ваш вопрос?

Другие вопросы по тегам