0
votes

I am creating an application using node.js , express. Today I tried to implement redis pubsub for sending notification to followers.

When a user logged in, I retrieve list of his fiends _id and subscribe to those _id as channel name. When any user update his status they publish notification to his channel. In my head it should work without any problem.

But for every user the redis client is same. So If one user subscribe to his friends _id then all of the users get notification on message on that channel.

What I did

on my app.js file -

...
// 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.");
  });
  
});

...

on my routes/user.js file

...
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('/'); 
    });

and example publish to channel -

....
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"});
    });
    ....
});
....

How can I create different client instance of redis sub client for different user? or is there any other way to do the same work?

TL;DR

How to implement facebook style friend's notification in node js express ? Can I use Redis PubSub? If then How?

1

1 Answers

0
votes

I just solve my problem by using express-socket.io-session . When user login I save his followers list in session object.

so my user.js file becomes

...

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

and my app.js file

...

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();
  });

});

...