При объединении socket.io/ node.js и redis pub/sub в попытке создать систему веб-вещания в режиме реального времени, управляемую событиями сервера, которые могут обрабатывать несколько транспортов, существует, по-видимому, три подхода:
-
'createClient' соединение redis и подписаться на каналы (каналы). При подключении клиента socket.io присоедините клиента к сокету. В событии redis.on( "сообщение",...) вызовите io.sockets.in(room).emit( "событие", данные), чтобы распространять все клиенты в соответствующей комнате. Как Как повторно использовать redis-соединение в socket.io?
-
'createClient' соединение redis. На соединение с клиентом socket.io, присоедините клиента в комнату socket.io и подпишитесь на соответствующие каналы (каналы) redis. Включите redis.on( "сообщение",...) в закрытие подключения клиента и при получении вызова клиента client.emit( "событие", данные), чтобы поднять событие на конкретном клиенте. Как ответ в Примеры использования RedisStore в socket.io
-
Используйте RedisStore, запеченный в socket.io и 'broadcast' из единственного канала отправки в Redis, следуя протоколу socketio-spec.
Номер 1 позволяет обрабатывать одно и другое событие Redis один раз для всех клиентов. Номер 2 предлагает более прямой крюк в Redis pub/sub. Число 3 проще, но мало контролирует события обмена сообщениями.
Однако в моих тестах все демонстрируют неожиданно низкую производительность с более чем одним подключенным клиентом. Рассматриваемые события сервера - это 1000 сообщений, опубликованных на канал redis, как можно быстрее, чтобы их можно было распространять как можно быстрее. Производительность измеряется таймингами на подключенных клиентах (на основе socket.io-client на основе данных времени журнала в списке Redis для анализа).
Что я предполагаю, так это то, что в варианте 1 сервер получает сообщение, а затем последовательно записывает его всем подключенным клиентам. В варианте 2 сервер получает каждое сообщение несколько раз (один раз на клиентскую подписку) и записывает его соответствующему клиенту. В любом случае сервер не попадает во второе сообщение, пока он не будет передан всем подключенным клиентам. Ситуация явно усугубляется ростом concurrency.
Это, по-видимому, противоречит воспринимаемой мудрости возможностей стеков. Я хочу верить, но я боюсь.
Является ли этот сценарий (распределение с низкой задержкой большого объема сообщений) просто не вариантом с этими инструментами (пока?), или я пропустил трюк?