Nodejs中node+socket.io 数据会重复发多次?

Nodejs中node+socket.io 数据会重复发多次?

    var io = require(‘socket.io’).listen(app);
io.configure(function () {
io.set(“transports”, [“xhr-polling”]);
io.set(“polling duration”, 100);
}); io.sockets.on(‘connection’, function (socket) { socket.broadcast.emit(‘system’, ‘[’ + name + ‘]上线了…’);

socket.on('public message', function (data) {       
    socket.broadcast.emit('public message', data); 
});

  socket.on('disconnect', function () {
     socket.broadcast.emit('system', '[' + name + ']下线了....');   
});

});

客户端:

 socket.on('connect', function () {
          socket.on('public message', function (data) {
            $("#show").append(data);
        });
            //显示系统广播
        socket.on('system', function (data) {
            $("#show").append('<span style=color:red>系统信息:' + data + '</span><br/>');
        });
    
    });

运行后,打开2个浏览器,先开始正常,打开一个,然后再打开另一个,会正常提示XXX上线了,发信息也没有问题。

但是2个浏览器不做任何操作后(没有关闭浏览器),一段时间,会提示XXX下线了。再过一段时间又自动XXX上线了,而且以后的数据都是重复的,比如发送消息:“你好”,然后另一个浏览器里会显示两边**“你好”**,用这个浏览器回复消息没有问题,会正常显示1条消息。

网上搜了很久,都没找到答案。 是不是

io.set("transports", ["xhr-polling"]);
io.set("polling duration", 100);

设置有问题


4 回复

这个问题通常与Socket.IO的连接管理有关。xhr-polling是一种长时间轮询的方式,可能会导致连接不稳定或重复连接。为了确保数据不会重复发送,我们可以尝试使用WebSocket协议,并且优化服务器端和客户端的事件处理逻辑。

示例代码

服务器端代码

var app = require('http').createServer(handler);
var io = require('socket.io')(app);

app.listen(3000);

function handler(req, res) {
    res.writeHead(200);
    res.end('Welcome to the server');
}

io.on('connection', function(socket) {
    var name = socket.handshake.query.name;
    
    socket.broadcast.emit('system', '[' + name + ']上线了...');
    
    socket.on('public message', function(data) {
        socket.broadcast.emit('public message', data);
    });

    socket.on('disconnect', function() {
        socket.broadcast.emit('system', '[' + name + ']下线了....');
    });
});

客户端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Socket.IO Test</title>
</head>
<body>
    <div id="show"></div>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io.connect('http://localhost:3000', {
            transports: ['websocket'],
            query: 'name=Client'
        });

        socket.on('connect', function() {
            console.log('Connected to server');
        });

        socket.on('public message', function(data) {
            $("#show").append('<p>' + data + '</p>');
        });

        socket.on('system', function(data) {
            $("#show").append('<span style="color:red">' + data + '</span><br/>');
        });
    </script>
</body>
</html>

解释

  1. 服务器端

    • 使用 io.on('connection') 监听新的连接。
    • 在连接时,广播一条系统消息。
    • 当接收到 public message 事件时,广播给其他所有连接的客户端。
    • 当客户端断开连接时,广播一条下线消息。
  2. 客户端

    • 使用 io.connect 连接到服务器,并传递查询参数 name
    • 监听 connect 事件以确认连接成功。
    • 监听 public messagesystem 事件,并将消息添加到页面上。

优化建议

  • 使用 websocket 协议而不是 xhr-polling,因为 WebSocket 提供了更稳定和高效的实时通信。
  • 确保客户端每次连接时都正确地处理事件,避免重复发送消息。

通过这些修改,可以减少数据重复发送的情况,并提高整体性能。


你把socket.io客户端升级到最新的0.9x的就好了

这个问题可能是由于Socket.IO的连接和断开机制导致的。xhr-polling传输方式可能会因为网络延迟或不稳定而频繁地重新建立连接。这会导致你在客户端看到重复的上线和下线通知以及消息重复。

解决方案

你可以尝试以下方法来解决这个问题:

  1. 避免重复监听事件: 确保每个事件只监听一次。例如,在客户端代码中,确保connect事件只监听一次,而不是每次连接时都添加新的监听器。

  2. 使用更可靠的传输方式: 尝试使用WebSocket或其他更稳定的传输方式,而不是xhr-polling。WebSocket是一种持久连接,性能更好,更适合实时通信。

  3. 检查Session管理: 如果你使用了Session管理,确保每个用户只有一个活跃的Socket连接。

示例代码

服务器端

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

io.on('connection', function(socket) {
    console.log('A user connected:', socket.id);

    socket.broadcast.emit('system', '[' + name + ']上线了...');

    socket.on('public message', function(data) {       
        socket.broadcast.emit('public message', data); 
    });

    socket.on('disconnect', function() {
        socket.broadcast.emit('system', '[' + name + ']下线了....');
    });
});

客户端

let socket = io();

socket.on('connect', function() {
    console.log('Connected to server');
});

socket.on('public message', function(data) {
    $("#show").append(data);
});

socket.on('system', function(data) {
    $("#show").append('<span style=color:red>系统信息:' + data + '</span><br/>');
});

socket.on('disconnect', function() {
    console.log('Disconnected from server');
});

通过这些调整,可以减少不必要的连接和断开事件,从而避免消息重复发送的问题。

回到顶部