MST

星途 面试题库

面试题:Node.js TCP 服务器的连接管理与异常处理

在 Node.js 创建的 TCP 服务器中,如何优雅地管理多个客户端连接,包括连接的建立、保持和断开?同时,针对可能出现的网络异常(如网络闪断、连接超时等),应如何设计健壮的异常处理机制?
28.2万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试
  1. 连接的建立
    • 在 Node.js 中创建 TCP 服务器,可以使用 net 模块。以下是基本示例:
    const net = require('net');
    const server = net.createServer((socket) => {
      // 新连接建立时的处理逻辑
      console.log('新客户端连接');
      socket.write('欢迎连接到服务器!\n');
    });
    server.listen(8080, () => {
      console.log('服务器已启动,监听端口 8080');
    });
    
    • 可以通过 server.on('connection', (socket) => {}) 来监听新连接事件,在回调函数中处理每个新连接。例如,可以为每个连接分配一个唯一标识,方便后续管理。
    let connectionId = 0;
    server.on('connection', (socket) => {
      const id = connectionId++;
      console.log(`新客户端连接,ID: ${id}`);
      socket.id = id;
    });
    
  2. 连接的保持
    • 心跳机制
      • 服务器和客户端之间定期发送心跳包。例如,服务器端可以这样实现:
      const net = require('net');
      const server = net.createServer((socket) => {
        const heartbeatInterval = setInterval(() => {
          if (socket.writable) {
            socket.write('心跳包\n');
          }
        }, 10000);
        socket.on('close', () => {
          clearInterval(heartbeatInterval);
        });
      });
      server.listen(8080, () => {
        console.log('服务器已启动,监听端口 8080');
      });
      
      • 客户端收到心跳包后回复,以保持连接活跃。如果服务器一段时间内没有收到客户端的回复,可以判定连接可能已断开。
    • 优化资源使用:合理设置 socketkeepAlive 选项。在服务器端创建 socket 时,可以这样设置:
    const net = require('net');
    const server = net.createServer((socket) => {
      socket.setKeepAlive(true, 10000); // 10 秒后发送 TCP keep - alive 包
    });
    server.listen(8080, () => {
      console.log('服务器已启动,监听端口 8080');
    });
    
  3. 连接的断开
    • 监听 socketclose 事件来处理连接断开。例如:
    const net = require('net');
    const server = net.createServer((socket) => {
      socket.on('close', () => {
        console.log('客户端连接已断开');
      });
    });
    server.listen(8080, () => {
      console.log('服务器已启动,监听端口 8080');
    });
    
    • 也可以通过 socket.destroy() 方法主动断开连接,比如在某些特定业务逻辑下,如检测到恶意行为等。
  4. 网络异常处理机制
    • 网络闪断
      • socket 上监听 error 事件。当网络闪断时,error 事件会触发。例如:
      const net = require('net');
      const server = net.createServer((socket) => {
        socket.on('error', (err) => {
          console.log('网络异常:', err.message);
          if (err.code === 'ECONNRESET') {
            // 连接被重置,可能是网络闪断等原因
            console.log('连接被重置,尝试重新连接(模拟客户端行为)');
            // 这里可以实现一些重连逻辑,如果是服务器端对外部服务的连接
          }
        });
      });
      server.listen(8080, () => {
        console.log('服务器已启动,监听端口 8080');
      });
      
    • 连接超时
      • 使用 socket.setTimeout(timeout) 方法设置连接超时时间。例如,设置 30 秒超时:
      const net = require('net');
      const server = net.createServer((socket) => {
        socket.setTimeout(30000);
        socket.on('timeout', () => {
          console.log('连接超时,关闭连接');
          socket.end();
        });
      });
      server.listen(8080, () => {
        console.log('服务器已启动,监听端口 8080');
      });
      

通过上述方法,可以较为优雅地管理 Node.js TCP 服务器中的多个客户端连接,并设计健壮的异常处理机制。