Nodejs写的server 崩溃了,这个socket错误看不明白.会报这个ECONNRESET Error,求高人帮忙看看

Nodejs写的server 崩溃了,这个socket错误看不明白.会报这个ECONNRESET Error,求高人帮忙看看

events.js:71 throw arguments[1]; // Unhandled ‘error’ event ^ Error: write ECONNRESET at errnoException (net.js:770:11) at Socket._write (net.js:552:19) at Socket.write (net.js:511:15) at sendMessage (D:\DevSpace\NewLobby\Lobby.js:527:11) at broadcastMessage (D:\DevSpace\NewLobby\Lobby.js:502:4) at Object.Lobby.onPlayerOffLine (D:\DevSpace\NewLobby\Lobby.js:103:4) at Socket.pro.listener (D:\DevSpace\NewLobby\lib\net\Server.js:103:19) at Socket.EventEmitter.emit (events.js:96:17) at Socket._destroy.destroyed (net.js:358:10) at process.startup.processNextTick.process._tickCallback (node.js:244:9)


5 回复

问题描述

你在运行一个用 Node.js 编写的服务器时遇到了 ECONNRESET 错误。这种错误通常表示客户端突然断开了连接,而你的服务器还在尝试向该客户端发送数据。

示例代码及分析

假设你有一个简单的聊天应用,其中服务器需要向所有在线用户广播消息。以下是可能引发 ECONNRESET 错误的代码片段:

// Lobby.js 文件
const net = require('net');

class Lobby {
    constructor() {
        this.clients = [];
    }

    onPlayerOffline(player) {
        // 移除已离线的玩家
        this.clients = this.clients.filter(client => client !== player.socket);
        
        // 尝试向所有客户端广播消息
        this.broadcastMessage("A player has left the game.");
    }

    broadcastMessage(message) {
        this.clients.forEach(client => {
            client.socket.write(message + '\n');
        });
    }
}

const lobby = new Lobby();

const server = net.createServer(socket => {
    lobby.clients.push({ socket });

    socket.on('end', () => {
        lobby.onPlayerOffline({ socket });
    });
});

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

问题原因

当一个客户端突然断开连接(比如网络中断或客户端主动关闭连接),Node.js 会触发 ECONNRESET 错误。此时,如果服务器继续尝试向这个已断开的客户端发送数据,就会抛出这个错误。

解决方案

为了处理这种情况,你需要确保在向客户端发送数据之前检查其连接状态。可以通过监听 error 事件来捕获这些错误,并优雅地处理它们。修改后的代码如下:

socket.on('error', (err) => {
    if (err.code === 'ECONNRESET') {
        console.error('Client disconnected unexpectedly.');
        // 从客户端列表中移除已断开连接的客户端
        lobby.clients = lobby.clients.filter(client => client.socket !== socket);
    }
});

通过这种方式,你可以避免因客户端断开连接而引起的崩溃,并且能够更稳健地处理客户端的断开事件。


错在这一行: D:\DevSpace\NewLobby\Lobby.js:527:11

贴出来看看

我不是高手。加上这个试试:

socket.on('error', function (exc) {
    sys.log("ignoring exception: " + exc);
});

另外 对出错部位用 try / catch, 这样程序可以报错,避免崩溃。

非常感谢.已经这么处理了…

从你提供的错误日志来看,你的Node.js服务器在处理网络通信时遇到了 ECONNRESET 错误。这个错误通常表示一个TCP连接在你尝试写入数据时被对端强制关闭了。

示例代码

假设你在使用Socket.IO或原生Node.js来创建一个简单的服务器,并且客户端可能在某个时刻断开了连接:

const net = require('net');

const server = net.createServer(socket => {
    socket.on('data', data => {
        console.log(`Received data: ${data}`);
        socket.write(`Echo: ${data}`);
    });

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

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

在这个例子中,如果客户端突然断开连接,而服务器尝试向这个已断开的连接写入数据,就会抛出 ECONNRESET 错误。

解决方案

  1. 处理error事件: 在任何网络通信相关的对象上监听error事件,可以让你捕获并处理这类错误,避免程序崩溃。

    socket.on('error', error => {
        console.error(`Socket error: ${error.message}`);
    });
    
  2. 确保资源清理: 当接收到endclose等事件时,确保所有资源都被正确清理,例如关闭文件描述符、取消定时器等。

  3. 使用更高级别的库: 使用如socket.io这样的库可以帮助你更好地管理WebSocket连接和状态,它会自动处理很多底层的细节。

通过以上方法,你可以更优雅地处理连接意外中断的情况,从而避免服务器因未捕获的异常而崩溃。

回到顶部