如何在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
相关产品推荐
相关产品推荐

