redis pub/sub 与 node.js 中的 socket.io

Posted

技术标签:

【中文标题】redis pub/sub 与 node.js 中的 socket.io【英文标题】:redis pub/sub with socket.io in node.js 【发布时间】:2012-08-12 21:02:30 【问题描述】:

我创建了简单的聊天应用程序。因此我使用了 node.js 我在网上看过很多简单的例子,都说代码运行良好。 但是当我尝试该代码时,它并没有给我正确的结果。

它抛出错误“丢弃传输”

我已阅读以下页面: 1)Examples in using RedisStore in socket.io 2)http://www.ranu.com.ar/2011/11/redisstore-and-rooms-with-socketio.html 3)socket.io broadcast function & Redis pub/sub architecture 4)I'm receiving duplicate messages in my clustered node.js/socket.io/redis pub/sub application 还有更多...

以下是我的代码:

服务器端代码:app.js ~~~~~~~~~~~~~~~~~~~~~~~~~

var app = express.createServer();
app.listen(process.env.PORT);

var io = require('socket.io').listen(app);

var store = redis.createClient();
var pub = redis.createClient();
var sub = redis.createClient();

var io = require('socket.io').listen(app);

io.configure(function () 

    //    io.enable('browser client minification');  // send minified client
    //    io.enable('browser client etag');          // apply etag caching logic based on version number
    //    io.enable('browser client gzip');          // gzip the file

    io.set('log level', 3);
    io.set("transports", ["jsonp-polling", "xhr-polling", "websocket", "flashsocket", "htmlfile"]);
    io.set("polling duration", 10);
    io.set("flash policy server", false);
    io.set("connect timeout", 500);
    io.set("reconnect", true);
    //    io.set('close timeout', 60 * 60 * 24); // 24h time out
    io.set('close timeout', 25);
    io.disable('heartbeats');
    io.set('heartbeat interval', 20);
    io.set('heartbeat timeout', 60);
    //    io.set("polling duration", 10);
    //    io.set("heartbate timeout", 30);
    //console.log("blabla");

    //var RedisStore = require('socket.io/lib/stores/redis');
    //io.set('store', new RedisStore( redisPub: pub, redisSub: sub, redisClient: store ));
    //io.set('store', new RedisStore());
);

io.sockets.on('connection', function (client) 

    client.on("OnConnect", function (data, fn) 
        console.log("socket id : " + client.id + " connected !!!");
    );

    client.on('disconnect', function () 
        console.log("\r\nmanish from server->disconnect");
        //        client.broadcast(client.sessionId + " disconnected")
        client.emit('user disconnected');
        sub.unsubscribe("chat");
        sub.quit();
    );

    sub.subscribe("chat");
    sub.on("message", function (channel, message) 
        console.log("message received on server from publish : '" + message + "'");
        client.send(message);
    );
  );
);

客户端代码:index.html ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

        this.Connect = function (nick, room) 
            socket = io.connect('http://XXX.XXX.X.XX',  transports: ['jsonp-polling', 'xhr-polling'] );
            Nickname = nick;
            Room = room;

//            setInterval(function ()  socket.emit("keep-alive", null) , 20 * 1000);

            socket.on('connect', function (data) 
                socket.emit('OnConnect',  nick: nick, room: room , function (response) 
                    $("#board").append("<p>" + response.msg + "</p>");
                );
            );

            socket.on("message", function (msg) 
                alert("message received on client ...");
                $("#board").append("<p>" + msg +"</p>");
            );

            server.on("listening", function () 
                var address = server.address();
                console.log("server listening " + address.address + ":" + address.port);
            );

            socket.emit("message",  msg: msg, nick: Nickname , function (response) 
                $("#board").append("<p> send message : " + Nickname + ": " + msg + "</p>");
            );

        ;

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 但它不适合我。

意味着我在一个浏览器中运行这个应用程序(比如说 Firefox,然后向第二个连接发送一些消息,比如说 IE)

但在 console.log 中显示以下错误

调试:设置请求 GET /socket.io/1/jsonp-polling/Th9U-Zci8cVb5Wfwl24Y?t=1345123231804&i=0 调试:设置轮询超时 调试:客户端授权 调试:清除轮询超时 调试:jsonppolling 写入 io.j0; 调试:为客户端 Th9U-Zci8cVb5Wfwl24Y 设置关闭超时 套接字 id:Th9U-Zci8cVb5Wfwl24Y 已连接!!! 从发布服务器上收到的消息:'msg 1' 调试:设置请求 GET /socket.io/1/jsonp-polling/Th9U-Zci8cVb5Wfwl24Y?t=1345123231804&i=0 调试:设置轮询超时 调试:客户端授权 调试:清除轮询超时 调试:jsonppolling 写入 io.j0; 调试:为客户端 Th9U-Zci8cVb5Wfwl24Y 设置关闭超时 套接字 id:Th9U-Zci8cVb5Wfwl24Y 已连接!!! 从发布服务器上收到的消息:'msg 1' 调试:为客户端 Th9U-Zci8cVb5Wfwl24Y 触发关闭超时 信息:传输结束(关闭超时) 调试:丢弃传输

【问题讨论】:

【参考方案1】:

Socket.io 房间开箱即用,您无需订阅 redis 或其他任何东西。

尝试在你的自定义连接函数上

client.on("OnConnect", function (data, fn) 
    console.log("socket id : " + client.id + " connected !!!");
    client.join(data.room);
);

你也不需要取消订阅房间,但如果你这样做应该是这样的

client.on('disconnect', function () 
    console.log("\r\nmanish from server->disconnect");
    client.emit('user disconnected');
    client.leave("chat");
);

向聊天室发送消息是通过 client.broadcast.to('chat').emit('message');

您可以在https://github.com/LearnBoost/socket.io/wiki/Rooms阅读有关房间的更多信息

祝你好运!

【讨论】:

以上是关于redis pub/sub 与 node.js 中的 socket.io的主要内容,如果未能解决你的问题,请参考以下文章

我在集群 node.js/socket.io/redis pub/sub 应用程序中收到重复消息

Node.js、Socket.io、Redis pub/sub 大容量、低延迟困难

Pub/Sub:似乎无法让本地模拟器与 Node.js 一起使用

socket.io 广播功能 & Redis pub/sub 架构

Redis Pub/Sub 发布订阅模式的深度解析与实现消息队列

redis源码阅读-发布与订阅pub/sub