Итак, я прочитал несколько статей о масштабировании Socket.IO. По разным причинам я не хочу использовать встроенный механизм масштабирования Socket.IO (в основном он кажется неэффективным, поскольку он публикует много нового для Redis, а затем требуется с моей точки зрения).Проблемы с клиентами Redis (в контексте Socket.IO)
Так что я пришел с этой простой идеей:
Каждый сервер Socket.IO создает Redis паб/суб/магазин клиентов, подключается к Redis и подписался на канал. Теперь, когда я хочу передавать данные, я просто публикую его в Redis, и все остальные серверы Socket.IO получают его и нажимают на пользователей.
Существует проблема, хотя (я думаю, это также проблема для встроенного механизма Socket.IO). Предположим, я хочу знать количество всех подключенных пользователей. Есть по крайней мере два способа сделать это:
Сервер публикует
give_me_clients
в Redis. Затем каждый сервер Socket.IO подсчитывает соединения и публикуетnumber_of_clients
. Сервер A захватывает эти данные, объединяет их и отправляет их клиенту.Каждый сервер обновляет
number_of_clients_for::ID_HERE
в Redis всякий раз, когда пользователь подключается/отключается от сервера. Затем сервер A извлекает данные и объединяет их. Может быть более эффективным.
Есть проблемы с этими решениями, хотя:
Сервер не знает о других серверах. Поэтому он не знает, когда он должен прекратить слушать
number_of_clients
. Можно исправить это, сделав Server A осведомленным о других серверах: всякий раз, когда сервер подключается к Redis, он публикуетnew_server
(сервер A захватывает данные и сохраняет их в памяти). Но что делать, когда ломается соединение Redis - Socket.IO? Есть ли способ для Redis уведомлять клиентов о том, что один из клиентов отключен?На самом деле то же, что и выше. Когда сбой сервера Socket.IO, как очистить данные
number_of_clients
?
Таким образом, реальный вопрос: может ли Redis уведомить (публиковать в chanel), что связь с одним из них только что закончилась?
Я также переключился на ws, и я в основном запускаю process.on exit и loop через 'wss.clients' и удаляю все' user: ids' в моем redis-хранилище (если сервер терпит неудачу). Одна простая проблема, с которой я столкнулась, - это личные сообщения. Если у меня было 2 ws-сервера на портах 9300 и 9301, и пользователь из 9301 хочет отправить сообщение пользователю, который находится в 9300 (или может быть любым другим сервером/портом), я не уверен, как разрешить другому пользователю знать. Разве я просто публикую приватный запрос на сервер redis и выясню, какой wss-сервер, на который пользователь отправил сообщение? –
@NiCkNewman Я думаю, что для каждого пользователя вы должны хранить информацию о том, на каком сервере этот пользователь (в одном общем месте, таком как Redis). Затем вы просто извлекаете эту информацию, и вы отправляете сообщение непосредственно на целевой сервер. Но самый эффективный способ сделать это - пользователь узнает, на каком сервере находится его друг, и отправляет сообщение прямо на этот сервер. – freakish
Конечно, все это зависит от контекста. Например, вы можете сохранить историю чата (например, Facebook), а затем все становится более сложным. У меня нет большого опыта работы с чат-серверами, поэтому я не хочу вести вас в неправильном направлении. :( – freakish