Why use redis in a chat application?

I just created a chat recently, it works very well, but I think I need to connect it to redis.

From what I understand, I need redis to scale and store some data if the client is updating or the server crashes.

The main component of 1on1 chat is that I store users and associate socket.idwith these users

var users = {};
io.sockets.on('connection', function (socket) {

  // store the users & socket.id into objects
  users[socket.handshake.headers.user.username] = socket.id;

});

Now, on the client side, I can say that I want to communicate with Jack, if this is a valid user, then I can transfer this data to the server, that is, the username and message.

var chattingWith = data.nickname; // this is Jack passed from the client side
io.to(users[chattingWith]).emit();

My question is: why should I use redis? What should I store in redis? How do I interact with this data?

I use io.adapter

io.adapter(redisIo({ 
  host: 'localhost', 
  port: 6379,
  pubClient: pub,
  subClient: sub
}));

, , , , redis .

// store stuff in redis
redisClientPublish.sadd('sockets:for:' + userKey + ':at:' + room_id, socket.id, function(err, socketAdded) {
  if(socketAdded) {
    redisClientPublish.sadd('socketio:sockets', socket.id);
    redisClientPublish.sadd('rooms:' + room_id + ':online', userKey, function(err, userAdded) {
      if(userAdded) {
        redisClientPublish.hincrby('rooms:' + room_id + ':info', 'online', 1);
        redisClientPublish.get('users:' + userKey + ':status', function(err, status) {
          io.sockets.in(room_id).emit('new user', {
            nickname: nickname,
            provider: provider,
            status: status || 'available'
          });
        });
      }
    });
  }
});

, .

app.get('/:id', utils.restrict, function(req, res) {

  console.log(redisClientPublish);

  utils.getRoomInfo(req, res, redisClientPublish, function(room) {

    console.log('Room Info: ' + room); 

    utils.getUsersInRoom(req, res, redisClientPublish, room, function(users) {

      utils.getPublicRoomsInfo(redisClientPublish, function(rooms) {

        utils.getUserStatus(req.user, redisClientPublish, function(status) {
          utils.enterRoom(req, res, room, users, rooms, status);
        });

      });

    });

  });

});

, , , - redis/ , , node.js "Jack" "" , node.js.

, , , Jack's "12333" "Mike's" "09278", , "" , "Mike/09278" .

redis, socket.id ?

+7
1

Redis - , , , . PubSub, , .

socket.io socket.io-redis

- - , - , , . socket.io-redis , Redis PubSub . , ( , ), , - .

, ? dev redis , socket.io, redis.

redis-cli
monitor

redis

redis - . , socket.io , , . . (, , ), . , .

/* note: untested pseudo code just for illustration */
io.sockets.on('connection', function (socket) {
    rooms = await redis.smembers("rooms:userA");
    rooms.foreach (function(room) {
        socket.join(room);
    }

    socket.on('leave', room) {
        socket.leave(room);
        redis.srem("rooms:userA", room);
    } 

    socket.on('join', room) {
        socket.join(room);
        redis.srem("rooms:userA", room);
    }
}

10 , Redis LIST

redis - . , . , push .

socket.on('chatmessage', room, message) {
    if (redis.lpush("conversation:userA:userB", "Hello World") > 10) {
        redis.rpop("conversation:userA:userB");
    }
    io.to(room).emit(message);
}

, lrange:

msgHistory = redis.lrange("conversation:userA:userB", 0, 10)

HASH

- /. - .

io.sockets.on('connection', function (socket) {
    redis.hset("userdata:userA", "status", "online");

    socket.on('disconnect', function () {
        redis.hset("userdata:userA", "status", "offline");
    }
}

" "

SET, , . , .

 socket.on('chatmessage', room, message) {
      io.to(room).emit(message);
      redis.zadd("conversations:userA", new Date().getTime(), room);
 }

 async function getTheTenLatestConversations() {
     return await redis.zrange("conversations:userA", 0, 10);
 }

+1

Source: https://habr.com/ru/post/1599174/


All Articles