node.js - 使用 redis pubsub 和 socket.io 的关注者状态更新通知

标签 node.js redis socket.io publish-subscribe node-redis

我正在使用 node.js express 创建一个应用程序。今天我尝试实现 redis pubsub 来向关注者发送通知。

当用户登录时,我检索他的 friend 列表 _id 并订阅这些 _id 作为 channel 名称。当任何用户更新他的状态时,他们会向他的 channel 发布通知。在我看来,它应该可以毫无问题地工作。

但是对于每个用户来说,redis 客户端都是一样的。因此,如果一个用户订阅了他的 friend _id,那么所有用户都会收到有关该 channel 消息的通知。

我做了什么

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

...

在我的 routes/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('/'); 
    });

和示例发布到 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"});
    });
    ....
});
....

如何为不同的用户创建不同的redis子客户端实例?还是有其他方法可以完成同样的工作?

长话短说

如何在node js express中实现facebook风格的好友通知?我可以使用 Redis PubSub 吗?如果那么如何?

最佳答案

我只是使用 express-socket.io-session 解决了我的问题.当用户登录时,我将他的关注者列表保存在 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();
  });

});

...

关于node.js - 使用 redis pubsub 和 socket.io 的关注者状态更新通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36909237/

相关文章:

javascript - Electron JS,使用 Express 后端和单独的 html 前端启动应用程序

maven - 使用 Maven 和 Spring Boot 的 Spring Session 示例中的 Redis 错误

node.js - 如何从 socket.io-redis 发送私有(private)消息(发出)

sockets - 套接字连接自动断开

node.js - 如何为redis请求设置 Node 超时

javascript - promise 无法正常工作

node.js - 为什么我没有从 jasmine-node 获得任何输出?

node.js - 我是否需要使用 .quit() 退出我的 Node redis 客户端实例?

node.js - Nodejs + Passport.js + Redis : how to store sessions in Redis

ios - objc 项目中 Socket.IO-Client-Swift 中的回调