Уведомление об обновлении статуса подписчиков с использованием redis pubsub и socket.io

Я создаю приложение, используя node.js, экспресс. Сегодня я попытался реализовать Redis pubsub для отправки уведомлений подписчикам.

Когда пользователь входит в систему, я получаю список его друзей _id и подписываюсь на эти _id как имя канала. Когда любой пользователь обновляет свой статус, он публикует уведомление на своем канале. В моей голове это должно работать без каких-либо проблем.

Но для каждого пользователя клиент Redis одинаков. Итак, если один пользователь подпишется на _id своих друзей, то все пользователи получат уведомление о сообщении на этом канале.

Что я сделал

в моем файле app.js -

...
// Because I wanted to publish from express route , so global
var redis = require('redis');
global.pub = redis.createClient();
global.sub = redis.createClient();
...

...
io.on('connection', function(socket){
  console.log(io.engine.clientsCount + " client connected.");
  global.socket = socket;
  
  sub.on("message", function(channel, message){
    console.log("Message "+ message + " on channel " + channel+ " arived");
    socket.emit('notification', {data: message});
  });
  
  socket.on('disconnect', function(){
    console.log(io.engine.clientsCount + " client after disconnecct.");
  });
  
});

...

в моем файле route/user.js

...
router.post('/login', function(req, res, next){
...
...
    Friendship.find({user2: req.session.userid}, function(err, doc){
        if (err) return console.dir(err);


        // req.session.followers = _.pluck(doc, 'user1');
        // console.log(req.session);

        /**
         * 
         */
        var userlist = _.pluck(doc, 'user1');
        console.dir(userlist);

        if(userlist.length != 0 ) {
            sub.subscribe(userlist);
        }

        res.redirect('/'); 
    });

и пример публикации на канале -

....
router.post('/progress', function(req, res, next){
    ....
    ....
    myPorgress.save(function(err){
        if(err) console.dir(err);
            
        pub.publish(req.myAuth.userid, myPorgress);
        res.json({message: "Book progress update successful"});
    });
    ....
});
....

Как я могу создать другой клиентский экземпляр подклиента Redis для другого пользователя? или есть ли другой способ сделать ту же работу?

TL;DR

Как реализовать уведомление друга в стиле facebook в node js express? Могу ли я использовать Redis PubSub? Если то Как?


person Ratan Parai    schedule 28.04.2016    source источник


Ответы (1)


Я просто решаю свою проблему, используя express-socket.io-session . Когда пользователь входит в систему, я сохраняю список его подписчиков в объекте сеанса.

поэтому мой файл user.js становится

...

var userlist = _.pluck(doc, 'user1');
    req.session.followers = userlist;
    console.dir(userlist);
    res.redirect('/'); 
...

и мой файл app.js

...

io.use(sharedsession(session, {
    autoSave:true
})); 

io.on('connection', function(socket){
  console.log(io.engine.clientsCount + " client connected.");

  //subscribe to friends updates
  var sub = redis.createClient();

  if(socket.handshake.session.followers){
    console.log("subscribing.. to " + socket.handshake.session.followers);
    sub.subscribe(socket.handshake.session.followers);
  }

  sub.on("message", function(channel, message){
    console.log("Message "+ message + " on channel " + channel+ " arived");
    socket.emit('notification', {data: message});
  });

  socket.on('disconnect', function(){
    console.log(io.engine.clientsCount + " client after disconnecct.");
    sub.quit();
  });

});

...
person Ratan Parai    schedule 28.04.2016