Какие методы существуют для сохранения веб-сокет соединений?

Как можно эффективно хранить пул соединений для вашего чат-приложения? Планирую использовать Redis для хранения, но столкнулся с проблемой сериализации объекта WebSocket. Существуют ли альтернативные методы хранения соединений, которые могут быть масштабируемыми? Возможно, есть способы сохранить соединения в Redis?
  • 5 января 2024 г. 20:38
Ответы на вопрос 3
WebSocket соединения — это постоянные, полнодуплексные соединения между клиентом и сервером, которые подразумевают установление TCP соединения. Поскольку WebSocket — это сетевой ресурс, он не может быть сериализован напрямую или сохранен в хранилище, такое как Redis, без потери своего состояния и функциональности.

Вот несколько стратегий управления WebSocket соединениями для масштабируемых чат-приложений:

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

2. Использование внутренней памяти:
   Если вы используете Node.js или другой серверный язык программирования, создайте внутреннюю структуру данных (например, объект Map в JavaScript), чтобы отслеживать активные соединения. Ключами в этой структуре могут быть идентификаторы пользователей, а значениями соответствующие объекты WebSocket.

3. Публикация/подписка или шаблоны сообщений (Pub/Sub):
   Рассмотрите использование модели Pub/Sub, предлагаемой Redis или другими системами сообщений (например, RabbitMQ, Kafka), для передачи сообщений между различными экземплярами серверов приложений. Все сервера подписываются на каналы, связанные с определёнными пользователями или комнатами чата, чтобы принимать и отправлять сообщения соответствующим образом.

4. Прокси WebSocket:
   Используйте WebSocket прокси (например, HAProxy) или балансировщик нагрузки, поддерживающий WebSocket, чтобы равномерно распределить нагрузку между различными экземплярами сервера. Это также может помочь в обеспечении бесперебойной работы сокетов при масштабировании системы.

5. Поддержка состояния узлов:
   Разработайте свою систему таким образом, чтобы каждый узел (сервер) мог хранить состояние соединений и обрабатывать локальные сообщения. Для сообщений, направляемых на другие узлы, используйте пересылку через центральное хранилище или Pub/Sub.

6. Стикки сессии (Sticky Sessions):
   При использовании нескольких экземпляров сервера убедитесь, что один и тот же клиент всегда подключается к одному и тому же серверу при использовании множества сокетных соединений. Это упрощает управление пользователями и их сессиями, поскольку их данные всегда сосредоточены на определённом сервере.

Таким образом, чтобы подход был масштабируемым, потребуется комбинировать несколько методов управления состоянием с сохранением в базе данных только тех данных, которые можно сериализовать, в том числе идентификаторы сессий или пользователей, а не сами объекты WebSocket.
Сокеты невозможно сериализовать. Придумай другую термиологию или другую идею. 

Возможно ты хотел что-то другое?
Ты не можешь сериализовать "пул вебсокет соединений". Если он сделан в рамках приложения, то он там будет жить весь лайфтайм этого приложения. А "чтобы соединения были в редисе" это значит что ты пул изначально сделал через pub/sub в redis. 
Другое дело, что ты можешь поднять несколько инстансов (как отдельные процессы, так и отдельные сервера), и сделать возможным обмен между этими инстансами, вот и всё масштабирование.
Похожие вопросы