Redis Pub/Sub 聊天室
Redis Pub/Sub ChatRooms
我是 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);
});
}
对于那里迷路的流浪者...我所做的是在客户端上实现另一个事件,基本上检查该客户端是否 'entitled' 消息(即消息的频道是否属于客户端列表字幕频道(如果有意义的话)。
客户端
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.
我是 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);
});
}
对于那里迷路的流浪者...我所做的是在客户端上实现另一个事件,基本上检查该客户端是否 'entitled' 消息(即消息的频道是否属于客户端列表字幕频道(如果有意义的话)。
客户端
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.