【问题标题】:Redis connections increasing from nodejsRedis 连接从 nodejs 增加
【发布时间】:2019-12-21 00:19:11
【问题描述】:

我有两个从 nodejs 到 Redis 的连接:

  1. 设置列表变量
  2. 订阅频道

套接字运行的时间越长,我得到的连接就越多。

我尝试在redis中设置超时值,尝试在socket.io关闭时关闭redis连接

var Redis = require('ioredis');
var globalRedis = new Redis({
  port: process.env.REDIS_PORT,          // Redis port
  host: process.env.REDIS_HOST,   // Redis host
  family: 4,           // 4(IPv4) or 6(IPv6)
  db: 1
});

[...]

io.sockets
  .on('connection', socketioJwt.authorize({
    secret: process.env.JWT_SECRET,
    timeout: 15000 // 15 seconds to send the authentication message
  }))
  .on('authenticated', function(socket) {
    var redis = new Redis({
      port: process.env.REDIS_PORT,
      host: process.env.REDIS_HOST,
      // password: process.env.REDIS_PASSWORD,
      family: 4,
      db: 1
    });

    socket.on('disconnect', function() {
      redis.unsubscribe('channel-'+socket.decoded_token.uid);
    });

    socket.on('error', function() {
      redis.unsubscribe('channel-'+socket.decoded_token.uid);
    });

    redis.subscribe('channel-'+socket.decoded_token.uid);

    redis.on('message', function(channel, message) {
      message = JSON.parse(message);
      socket.emit('message', message);  
    }); 
  });



function disconnectUser(userObject){
  globalRedis.sismember('online_uids', userObject.uid).then(function(){
    globalRedis.srem('online_users', userObject.nickname).then(console.log(userObject.nickname + ' disconnected!'));
    globalRedis.srem('online_uids', userObject.uid);
  });
}

const port = process.env.SOCKET_PORT;
const host = process.env.SOCKET_URL;
const logger = () => console.log(`Listening: http://${host}:${port}`);
http.listen(port, host, logger);

所以globalRedis 中的连接始终处于活动状态,没有任何问题。 但是随着时间的推移,redis 中的订阅连接会增加,即使我在断开连接和错误时取消订阅。

有什么想法吗?

P.S.:抱歉我的代码和知识不好,这是我的第一个 nodejs。

【问题讨论】:

    标签: node.js amazon-web-services redis publish-subscribe


    【解决方案1】:

    您正在为每个经过身份验证的套接字连接创建一个新的 redis 客户端,然后它正在订阅频道。
    从频道取消订阅不会关闭连接,超时仅适用于普通客户端,不适用于发布/订阅客户端。
    在socket断开或错误时关闭redis客户端连接。
    redis.quit()
    参考Redis Docs

    【讨论】:

    • 所以你的意思是把 unsubscribe 改成 unsubscribe+quit 对吧?
    • @Chris 是的。 redis.quit(); redis=null
    【解决方案2】:

    所以以防万一有人偶然发现同样的问题。我最终将每个用户放入了自己的频道:

    io.sockets
      .on('connection', socketioJwt.authorize({
        secret: process.env.JWT_SECRET,
        timeout: 15000 // 15 seconds to send the authentication message
      }))
      .on('authenticated', function(socket) {
        socket.join(socket.decoded_token.uid);
        connectUser(socket.decoded_token);
    
        socket.on('disconnect', function() {
          disconnectUser(socket.decoded_token);
        });
    
        socket.on('error', function() {
          disconnectUser(socket.decoded_token);
        });
        
        socket.on('connect_failed', function() {
          disconnectUser(socket.decoded_token);
        });
    
        socket.on('reconnect_failed', function() {
          disconnectUser(socket.decoded_token);
        });
    
        socket.on('message', function(message){
          socket.emit('message', message);
        });
    
      });
      redis.on('message', function(channel, msg)  {
        // console.log(msg);
        try{
          message = JSON.parse(msg);
          channels = message.data.socketchannel
            channels.forEach(recipient => {
            io.sockets.in(recipient).emit('message', message);
          })
        }
        catch(e) {
          const fs = require('fs');
          fs.writeFile("./log/errorlog"+ new Date().toJSON().slice(0,10), e, function(err) {
            if(err) {
                return console.log(err);
            }
          })
        }
        
      });
    

    【讨论】:

      猜你喜欢
      • 2011-05-10
      • 2021-09-05
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 2015-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多