You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS中检测客户端是否终止gRPC TCP连接?

在NestJS中检测gRPC双向流的TCP连接终止

核心思路

gRPC基于HTTP/2,TCP连接断开属于底层连接异常,会通过流的error事件抛出;同时也可以通过获取底层HTTP/2连接来监听全局连接关闭事件(适用于需要感知整个连接生命周期的场景)。

具体实现

1. 监听流的error事件

当客户端TCP连接意外断开时,gRPC流会触发error事件,错误对象中会包含连接相关的错误码(如ECONNRESET)。你可以在流的处理逻辑中添加这个事件监听:

@GrpcStreamCall('StreamService', 'openStream')
async openStream(requestStream: ServerDuplexStream<Message, Message>) {
  // 处理正常流关闭
  requestStream.on('close', async () => {
    console.log('gRPC流已正常关闭');
  });

  // 监听连接异常(含TCP断开)
  requestStream.on('error', (err) => {
    // 判断是否为TCP连接断开类错误
    if (err.code === 'ECONNRESET' || err.message.includes('Connection closed')) {
      console.log('客户端TCP连接已终止');
      // 在这里执行清理逻辑,比如释放资源、标记客户端离线等
    } else {
      // 处理其他gRPC错误
      console.error('gRPC流发生错误:', err);
    }
  });

  // 处理流消息逻辑
  requestStream.on('data', (message: Message) => {
    // 处理客户端发送的消息
    requestStream.write({ /* 响应消息 */ });
  });
}

2. 监听底层HTTP/2连接的关闭事件

如果需要感知整个TCP连接的生命周期(而非单个流),可以通过gRPC流获取底层的HTTP/2连接,然后监听其close事件:

import { ServerDuplexStream } from '@grpc/grpc-js';

@GrpcStreamCall('StreamService', 'openStream')
async openStream(requestStream: ServerDuplexStream<Message, Message>) {
  // 获取底层HTTP/2连接
  const http2Conn = requestStream.getChannel()?.getConnection();
  if (http2Conn) {
    const handleConnClose = () => {
      console.log('客户端TCP连接已关闭');
      // 执行全局连接清理逻辑
    };
    http2Conn.on('close', handleConnClose);

    // 记得在流关闭时移除监听,避免内存泄漏
    requestStream.on('close', () => {
      http2Conn.off('close', handleConnClose);
    });
  }

  // 其他流处理逻辑...
}

注意事项

  • error事件会覆盖所有异常场景,包括TCP断开、协议错误等,需要通过错误码/消息区分具体原因。
  • 底层HTTP/2连接的close事件会在整个TCP连接关闭时触发,此时该连接上的所有gRPC流都会受到影响,适合做全局连接级别的清理。
  • 务必在流关闭时移除对HTTP/2连接的监听,防止内存泄漏。

内容的提问来源于stack exchange,提问作者rook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 16:03:24