React与Node.js WebSocket连接几秒后断开,寻求解决方案
解决WebSocket连接自动断开的问题
1. 修复服务器端的close事件处理
你的服务器在close事件里重复调用ws.close(),会导致连接异常关闭,同时未清理connectedClients中的无效连接,可能引发后续问题。修改如下:
ws.on('close', () => { // 从连接列表中移除已关闭的客户端 delete connectedClients[clientId]; console.log(`Client ${clientId} disconnected`); });
2. 实现服务器端的ping/pong响应
客户端配置了心跳机制,但服务器未处理ping消息并返回pong,客户端会因收不到响应判定连接失效。添加ping消息处理逻辑:
ws.on('message', async (message) => { console.log(`Received message from ${clientId}: ${message}`); console.log(Object.keys(connectedClients)); // 处理心跳ping,返回pong if (message === 'ping') { ws.send('pong'); return; } // 原有的结果文件检查逻辑 if (fs.existsSync(`output/${clientId}_results.csv`)) { const resultPath = path.join(__dirname, 'output', `${clientId}_results.csv`); const output = []; await new Promise((resolve, reject) => { fs.createReadStream(resultPath) .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", (row) => {output.push(row)}) .on('end', resolve) .on('error', reject) }) sendMessageToClient(clientId, JSON.stringify(output)); } });
3. 调整客户端的filter配置
客户端设置filter: () => false会过滤所有消息,包括心跳的pong响应,导致react-use-websocket的心跳机制无法正常工作,进而触发连接断开。如果不需要过滤消息,直接移除该配置;若需过滤特定消息,调整filter逻辑让心跳相关消息通过:
const { sendMessage, sendJsonMessage, lastMessage, lastJsonMessage, readyState, getWebSocket, } = useWebSocket(`${WS_URL}/${submissionID}`, { share: false, // 移除filter,或者调整为只过滤非心跳/非结果消息 // filter: (message) => message.data !== 'pong' && message.data !== 'ping', onOpen: () => { console.log('Opened websocket'); sendMessage(submissionID); }, // ... 其他配置不变 });
4. 完善服务器端的错误处理
添加error事件监听,避免未捕获的错误导致连接意外关闭:
ws.on('error', (error) => { console.error(`WebSocket error for client ${clientId}:`, error); delete connectedClients[clientId]; });
5. 检查sendMessageToClient函数实现
确保sendMessageToClient函数正确处理发送逻辑,当连接已关闭时清理无效连接:
function sendMessageToClient(clientId, message) { const client = connectedClients[clientId]; if (client && client.readyState === WebSocket.OPEN) { try { client.send(message); } catch (error) { console.error(`Failed to send message to ${clientId}:`, error); delete connectedClients[clientId]; } } else { console.log(`Client ${clientId} is not connected`); delete connectedClients[clientId]; } }
通过以上修改,WebSocket连接的心跳机制会正常工作,连接不会因为未响应的ping而断开,同时避免了异常的close处理和无效连接的内存泄漏问题。
内容的提问来源于stack exchange,提问作者tensormoby
相关产品推荐
相关产品推荐

