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.
就是传输过久没收到回应,就会重新建立一个连接
这个问题困扰我好几天了,求高手拯救
Node.js 中 socket.io 的 xhr-polling 问题:网速太慢导致连接延迟与重连
问题描述
我在本地使用 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
文档,如果在协商的超时时间内没有收到回应,连接会被认为已经断开。此时客户端可能会决定重新建立连接,这会导致频繁的手动握手。
解决方案
可以通过调整 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
是一种长时间轮询的方式,客户端每隔一段时间会向服务器发送请求以检查是否有新的消息,这在低带宽或高延迟的网络环境中可能会导致性能问题。
解决方案
- 优化网络条件:如果可能,改善网络环境,比如提高带宽、减少网络延迟。
- 调整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');
});
通过上述配置,可以更好地应对网络条件较差的情况,从而减少重连次数和延迟。