2012-06-20 3 views
2

Итак, я прочитал несколько статей о масштабировании Socket.IO. По разным причинам я не хочу использовать встроенный механизм масштабирования Socket.IO (в основном он кажется неэффективным, поскольку он публикует много нового для Redis, а затем требуется с моей точки зрения).Проблемы с клиентами Redis (в контексте Socket.IO)

Так что я пришел с этой простой идеей:

Каждый сервер Socket.IO создает Redis паб/суб/магазин клиентов, подключается к Redis и подписался на канал. Теперь, когда я хочу передавать данные, я просто публикую его в Redis, и все остальные серверы Socket.IO получают его и нажимают на пользователей.

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

  1. Сервер публикует give_me_clients в Redis. Затем каждый сервер Socket.IO подсчитывает соединения и публикует number_of_clients. Сервер A захватывает эти данные, объединяет их и отправляет их клиенту.

  2. Каждый сервер обновляет number_of_clients_for::ID_HERE в Redis всякий раз, когда пользователь подключается/отключается от сервера. Затем сервер A извлекает данные и объединяет их. Может быть более эффективным.

Есть проблемы с этими решениями, хотя:

  1. Сервер не знает о других серверах. Поэтому он не знает, когда он должен прекратить слушать number_of_clients. Можно исправить это, сделав Server A осведомленным о других серверах: всякий раз, когда сервер подключается к Redis, он публикует new_server (сервер A захватывает данные и сохраняет их в памяти). Но что делать, когда ломается соединение Redis - Socket.IO? Есть ли способ для Redis уведомлять клиентов о том, что один из клиентов отключен?

  2. На самом деле то же, что и выше. Когда сбой сервера Socket.IO, как очистить данные number_of_clients?

Таким образом, реальный вопрос: может ли Redis уведомить (публиковать в chanel), что связь с одним из них только что закончилась?

ответ

2

После многих испытаний кажется, что у Redis нет такой функциональности. Также я выяснил, что масштабирование Socket.IO действительно является болью.

Итак, я переключился с Socket.IO на WS (см. this link). Это низкий уровень (но идеально подходит для моего использования), и он поддерживает только WebSockets (во всех основных версиях). Но с другой стороны, я хочу только поддерживать WebSockets и FlashSocket (которые я должен использовать, но это нормально).

Преимущество в том, что я могу легко создать кластер с такими серверами. HAProxy работает с такими серверами почти из коробки (небольшая настройка). Серверы могут легко обмениваться данными в локальной сети (с UDP или центральным TCP-сервером, если кластер большой).

Недостаток заключается в том, что нужно вручную реализовать некоторые классные функции, такие как сердцебиение, радиовещание, комнаты и т. Д. Также вы хотите иметь длинный опрос, но это нормально в моем случае. Масштабирование еще более важно, imho.

+0

Я также переключился на ws, и я в основном запускаю process.on exit и loop через 'wss.clients' и удаляю все' user: ids' в моем redis-хранилище (если сервер терпит неудачу). Одна простая проблема, с которой я столкнулась, - это личные сообщения. Если у меня было 2 ws-сервера на портах 9300 и 9301, и пользователь из 9301 хочет отправить сообщение пользователю, который находится в 9300 (или может быть любым другим сервером/портом), я не уверен, как разрешить другому пользователю знать. Разве я просто публикую приватный запрос на сервер redis и выясню, какой wss-сервер, на который пользователь отправил сообщение? –

+1

@NiCkNewman Я думаю, что для каждого пользователя вы должны хранить информацию о том, на каком сервере этот пользователь (в одном общем месте, таком как Redis). Затем вы просто извлекаете эту информацию, и вы отправляете сообщение непосредственно на целевой сервер. Но самый эффективный способ сделать это - пользователь узнает, на каком сервере находится его друг, и отправляет сообщение прямо на этот сервер. – freakish

+0

Конечно, все это зависит от контекста. Например, вы можете сохранить историю чата (например, Facebook), а затем все становится более сложным. У меня нет большого опыта работы с чат-серверами, поэтому я не хочу вести вас в неправильном направлении. :( – freakish

Смежные вопросы