Redis Pub / Sub ChatRooms

时间:2015-10-19 20:50:47

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

我对Redis Pub / sub很新,所以请耐心等待。我正在尝试创建一个IRC,用户可以在其中创建自己的聊天室,有点像Gitter。以下是我到目前为止所做的事情。我正在通过用户名将用户订阅到不同的频道仅用于测试。事实是,当我发布到频道x时,一个接收到频道y的客户端仍然会得到相同的信息。消息..我正在使用redis-cli和PUBLISH命令发布。

function handleIO(socket){
    function disconnect(){
        console.log("Client disconnected");
        socket.broadcast.emit("user d/c", socket.username+" has left!");
    }

    socket.on("new user", function(username){
        socket.username = username;

        if(socket.username == "chat"){
            redisClient.subscribe("chat");
        }else{
            redisClient.subscribe("other");
        }

        socket.userColor = '#'+(Math.random()*0xFFFFFF<<0).toString(16);
        socket.emit("new_user", username);

        emitter.lrange("messages", 0, -1, function(err, messages){
            //reversing to be in correct order
            messages = messages.reverse();

            messages.forEach(function(message){
                message = JSON.parse(message);
                socket.emit("messages", message);
            });
        });

        socket.broadcast.emit("user connection", username+" has connected to the Haven!");
    });
    socket.on("disconnect", disconnect);

    socket.on("send", function(msg){
        var msg = JSON.stringify( { name: socket.username, messageText: msg, color: socket.userColor } );

        emitter.lpush("messages", msg, function(err, response){
            //keep newest 10 items
            emitter.ltrim("messages", 0, 9);
        });
        io.sockets.emit("receive", msg, socket.userColor);
    });
    redisClient.on("message", function (channel, message) {
        console.log(channel+":"+message);
        socket.emit("message", channel, message);
    });

}

1 个答案:

答案 0 :(得分:1)

对于那里迷失的流浪者...我所做的是在客户端上实现另一个事件,基本上检查该客户端是否“有权”使用该消息(即消息的频道是否属于客户端的底层频道列表中那讲得通)。

客户端

socket.on("message", function(channel, message){
     socket.emit("entitled", channel, message);
});

socket.on("entitled", function(reply, channel, message){
     if(reply == 1){
          $("#msgArea").append(message+"<br/>");
          $("#msgArea").prop({ scrollTop: $("#msgArea").prop("scrollHeight") });    
     }
});

服务器侧

socket.on("entitled", function(channel, message){
    //check that user is subbed 
    emitter.sismember('channels:'+socket.username, channel, function(err, reply){
        if(err) throw err;
        socket.emit("entitled", reply, channel, message);
    });
});

我故意遗漏的是我没有继续使用socket.username但是开始使用会话来持久化。我的建议是坚持使用redis商店,因为它是github上最受欢迎的商店之一。