如何在Socket.IO中使用xhr-polling存储持久数据?

时间:2012-03-02 11:09:20

标签: javascript node.js chat socket.io

我正在用Node.js和Socket.IO编写一个多房间聊天应用程序,我想知道如何处理在会话期间需要持久存储的数据,当传输是xhr-polling时。 / p>

目前,在客户端上,我正在连接上发送一个“join”事件,它传递了一些长的变量(例如用户名),我使用Socket.IO的get和set方法存储服务器端。然后它们可用,直到客户端断开连接。

如果传输是Websockets,这可以正常工作,但如果它回退到xhr-polling,则会在每个连接上发出join事件,每5-10秒发生一次。 (类似地,在每个xhr-poll请求中发送“此类已经离开/加入房间”,这也是不可取的。)

我不确定前进的最佳方式是什么。我无法禁用xhr-polling,因为它是一个无闪存IE浏览器所需的后备。

以下是相关的客户代码:

socket.on("connect", function(){
    socket.emit("join", { username: username, room: room });
});

在服务器上:

var io = require("socket.io").listen(8124)
, buffer = {}
, max_room_buffer = 15;

io.sockets.on("connection", function(socket) {
    socket.on("join", function(data){
        if(data.username && data.room) {
        socket.set("data", data);
        socket.join(data.room);
        if(!buffer[data.room]) buffer[data.room] = [];
        socket.broadcast.to(data.room).emit("message", "<em>" + data.username + " has joined room " + data.room + "</em>");
        socket.emit("message", "<em>You have joined room " + data.room + "</em>");
        socket.emit("message", buffer[data.room]);
    }
});

socket.on("message", function(message) {
    if(message) {
        socket.get("data", function(err, data){
            if(data) {
                var msg = "<span>" + data.username + ":</span> " + message;
                buffer[data.room].push(msg);
                if(buffer[data.room].length > max_room_buffer) buffer[data.room].shift();
                io.sockets.in(data.room).emit("message", msg);
            }
        });
    }
});

socket.on("disconnect", function () {
    socket.get("data", function(err, data){
        if(data) {
            socket.leave(data.room);
            socket.broadcast.to(data.room).emit("message", "<em>" + data.username + " has left room " + data.room + "</em>");
        }
    });
});

});

提前致谢。

1 个答案:

答案 0 :(得分:2)

也许我错过了什么,但这不会有用。

<强>客户端:

var firstJoin = true;
socket.on("connect", function(){
    socket.emit("join", { username: username, room: room, firstJoin: firstJoin });
    firstJoin = false;
});

服务器

io.sockets.on("connection", function(socket) {
    socket.on("join", function(data){
        if(data.username && data.room) {
        socket.set("data", data);
        socket.join(data.room);
        if(!buffer[data.room]) buffer[data.room] = [];

        if (data.firstJoin) {
            socket.broadcast.to(data.room).emit("message", "<em>" + data.username + " has joined room " + data.room + "</em>");
            socket.emit("message", "<em>You have joined room " + data.room + "</em>");
            socket.emit("message", buffer[data.room]);
        }
    }
});

关于连接事件在每次新的轮询中发生的事实,这是XHR轮询的不可避免的后果。由于每个轮询都是一个新的HTTP请求,因此上一个请求没有状态,因此您需要重新设置它。

如果您想减少这种情况发生的频率,可以尝试将轮询持续时间从默认值20增加。例如:

io.configure(function() {
    io.set('polling duration', 60);
});