Реализация Pub / Sub в nodeJS - PullRequest
13 голосов
/ 05 мая 2011

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

Я начал с socket.io, создал базовый массив каналов, и когда пользователи отправляли сообщения,он просматривает пользователей в этом канале и отправляет сообщение клиенту пользователя.Это работало хорошо, и у меня не было с этим проблем.

Для сохранения объектов я добавил поддержку Redis с помощью node_redis.Затем я заменил цикл client.send в массиве каналов на Redis pub / sub как слой абстракции.Но я заметил, что мне нужно было создать новый клиент Redis для каждого пользователя, который сделал подписку.И мне все еще нужно было хранить информацию о клиенте socket.io для отправки сообщений на публикацию.Насколько это масштабируемо?Есть ли другие (лучшие) реализации или дальнейшие оптимизации, которые я мог бы сделать?Что бы вы сделали?

Ответы [ 5 ]

7 голосов
/ 09 мая 2011

Для сохранения объекта я добавил поддержку Redis, используя node_redis.Затем я заменил цикл client.send в массиве каналов на Redis pub / sub как слой абстракции.Но я заметил, что мне нужно было создать новый клиент Redis для каждого пользователя, который сделал подписку.И мне все еще нужно было хранить информацию о клиенте socket.io для отправки сообщений на публикацию.Насколько это масштабируемо?Есть ли другие (лучшие) реализации или дальнейшие оптимизации, которые я мог бы сделать?Что бы вы сделали?

Да, вы должны создавать новый клиент Redis для каждого запроса ввода-вывода.Это тяжелый и не масштабируемый.Но создание нового подключения клиента Redis не занимает много памяти.Так что, если количество пользователей вашей системы не превышает 5000, это нормально.Для масштабирования вы можете добавить в подчиненный сервер Redis, чтобы разрешить интенсивную публикацию и подписку, и если вы беспокоитесь о создании большого количества подключений, вы можете увеличить вашу ОС uLIMIT.

Вам не нужно хранить сокет.IO клиент в сообщении отправлено.После того, как redis получил подписанное сообщение канала.Он отправит сообщение определенному клиенту io.

subscribe.on("message",function(channel,message) { 
 var msg = { message: [client.sessionId, message] }; 
 buffer.push(msg);
 if (buffer.length 15) buffer.shift(); 
 client.send(msg); > });

Чтобы подписаться на несколько каналов.Я предлагаю вам предварительно сохранить всех пользователей с более чем одним каналом (вы можете использовать хранилище Mongodb или Redis).

var store = redis.createClient();
var subscriber= redis.createClient()

store.hgetall(UID, function(e, obj){
     subscriber.subscribe(obj.ChannelArray.toArray());
 })
4 голосов
/ 05 мая 2011

Я использую Faye.js .Серьезно простейшая реализация pub / sub, которую я смог найти.Может быть, это поможет!

2 голосов
/ 10 мая 2011

Или вы можете попробовать Джаггернаут. Это с помощью socket.io + redis pub sub middleware + node.js. Поддержите все транспорты. Это поможет вам обработать все каналы подписки или публикации между клиентом и Redis. Juggernaut является масштабируемым, но он затрагивает только накладные расходы на redis и не поддерживает аутентификацию (вы можете с этим справиться) Однако redis может записывать / читать> 150 кбит / с, поэтому для вашего случая это не должно быть проблемой.

https://github.com/maccman/juggernaut

2 голосов
/ 06 мая 2011

Попробуйте взглянуть на этот вопрос о redis pub / sub и socket.io.

1 голос
/ 09 мая 2011

FYI Socket.io v0.7 будет поддерживать каналы и должен упростить существующий код (больше никаких зависимостей pub / sub lib)

См .: http://cl.ly/0B0C3f133K1m3j422n0K

...