Nodejs中socket.io的xhr-polling问题,网速太慢导致连接延迟与重连

Nodejs中socket.io的xhr-polling问题,网速太慢导致连接延迟与重连

为什么我本地用xhr-polling方式传输数据没有问题 放到了空间上就各种蛋疼,websocket是没问题的

成功握手,就是取不到数据 握手响应:dPthxeIT4hOQqlzYklMV:60:60:xhr-polling,jsonp-polling

握手后的请求 http://host:8888/socket.io/1/xhr-polling/dPthxeIT4hOQqlzYklMV?t=1355038220437 OK 继续请求,发送事件信息 http://host:8888/socket.io/1/xhr-polling/dPthxeIT4hOQqlzYklMV?t=1355038220662 404 Not found

看了下socket.io-spec 我猜测是这个问题: If the connection is not resumed within the negotiated timeout the socket is considered disconnected. At this point the client might decide to reconnect the socket, which implies a new handshake.

就是传输过久没收到回应,就会重新建立一个连接

这个问题困扰我好几天了,求高手拯救


4 回复

Node.js 中 socket.io 的 xhr-polling 问题:网速太慢导致连接延迟与重连

问题描述

我在本地使用 xhr-polling 方式传输数据时一切正常,但将应用部署到服务器后,xhr-polling 方式出现了连接延迟和频繁重连的问题。而 WebSocket 方式则没有问题。

具体现象

  1. 成功握手,但是无法获取到数据。
  2. 握手响应如下:
    dPthxeIT4hOQqlzYklMV:60:60:xhr-polling,jsonp-polling
    
  3. 握手后的请求如下:
    http://host:8888/socket.io/1/xhr-polling/dPthxeIT4hOQqlzYklMV?t=1355038220437
    
    请求成功,返回 OK
  4. 然后继续请求,发送事件信息:
    http://host:8888/socket.io/1/xhr-polling/dPthxeIT4hOQqlzYklMV?t=1355038220662
    
    返回 404 Not Found

原因分析

根据 socket.io-spec 文档,如果在协商的超时时间内没有收到回应,连接会被认为已经断开。此时客户端可能会决定重新建立连接,这会导致频繁的手动握手。

解决方案

可以通过调整 socket.io 的配置来解决这个问题。例如,增加超时时间,减少重连次数等。

const io = require('socket.io')(server, {
    transports: ['xhr-polling'],
    pingTimeout: 30000, // 增加 ping 超时时间
    pingInterval: 25000, // 增加 ping 间隔时间
    reconnectionAttempts: 5, // 减少重连尝试次数
    reconnectionDelay: 1000, // 增加重连延时
});

io.on('connection', (socket) => {
    console.log('Client connected');

    socket.on('disconnect', () => {
        console.log('Client disconnected');
    });

    socket.on('event', (data) => {
        console.log('Event received:', data);
        socket.emit('response', 'Data received');
    });
});

总结

通过调整 socket.io 的配置参数,可以有效缓解 xhr-polling 方式下的连接延迟和频繁重连问题。希望这个解决方案能帮助你解决问题。


我也遇到这个问题,客户端很久才收到数据,有时候根据就收不到,我想采取flashsocket协议,可是部署完了后,在本地测试没问题,在服务器上就IE就连不上了,切换协议有问题,真奇怪……还是解决中……

我用的是nginx + tcp module

最后确定可能是我们用到的F5负载均衡器的原因,排除nginx+ tcp module问题。

根据你的描述,问题主要在于网络环境较慢时,使用 xhr-polling 方式时的连接延迟与重连问题。xhr-polling 是一种长时间轮询的方式,客户端每隔一段时间会向服务器发送请求以检查是否有新的消息,这在低带宽或高延迟的网络环境中可能会导致性能问题。

解决方案

  1. 优化网络条件:如果可能,改善网络环境,比如提高带宽、减少网络延迟。
  2. 调整Socket.IO配置:可以通过配置项来调整心跳检测的时间间隔以及重连策略。

以下是一些具体的操作步骤:

1. 调整Socket.IO的配置

你可以通过配置Socket.IO来改变其默认的行为,特别是心跳检测的时间间隔和重试次数。

const io = require('socket.io')(server, {
    transports: ['polling', 'websocket'], // 明确指定支持的传输方式
    pingTimeout: 5000, // 心跳超时时间(毫秒)
    pingInterval: 25000, // 心跳间隔时间(毫秒)
    reconnection: true, // 允许自动重连
    reconnectionDelay: 1000, // 初始重连延时(毫秒)
    reconnectionDelayMax : 5000, // 最大重连延时(毫秒)
    reconnectionAttempts: 5 // 最大重连尝试次数
});

2. 检查服务端错误

确保你的服务器能够正确处理所有的请求,并且不会返回404错误。如果你的服务端代码有误,可能导致Socket.IO的xhr-polling请求失败。

示例代码

假设你有一个简单的HTTP服务器,并希望启用Socket.IO,这里是一个基本的示例:

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
    transports: ['polling', 'websocket'],
    pingTimeout: 5000,
    pingInterval: 25000,
    reconnection: true,
    reconnectionDelay: 1000,
    reconnectionDelayMax : 5000,
    reconnectionAttempts: 5
});

io.on('connection', (socket) => {
    console.log('A user connected');
    
    socket.on('disconnect', () => {
        console.log('User disconnected');
    });
});

server.listen(3000, () => {
    console.log('Server listening on port 3000');
});

通过上述配置,可以更好地应对网络条件较差的情况,从而减少重连次数和延迟。

回到顶部