Реализация Pub/ Sub в nodeJS

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

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

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

5 ответов

Решение

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

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

Вам не нужно хранить клиент socket.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());
 })

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

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

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

https://github.com/maccman/juggernaut

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

Смотрите: http://cl.ly/0B0C3f133K1m3j422n0K

Другие вопросы по тегам