【问题标题】:How to handle when client disconnects on NestJS当客户端在 NestJS 上断开连接时如何处理
【发布时间】:2022-01-13 09:31:33
【问题描述】:

我正在使用 NestJS,我需要知道客户端何时强制断开连接取消 > 它。 (要么是错误的,要么是因为他们想要)。

例如,在 Express 中很简单:

const express = require('express')
const app = express()
const port = 3000

app.get('/', (expressRequest, expressResponse) => {

    // Detecting close event
    expressRequest.on('close', function() {
        console.log('Client connection closed....!');
    });
    // Detecting end event
    expressRequest.on('end', function() {
        console.log('Client connection end....!');
    });

    expressResponse.send('Hello World!')
})

app.listen(port, () => {
    console.log(`Example app listening at http://localhost:${port}`)
})

问题是:使用 NestJS,正确的做法是什么?

【问题讨论】:

  • 我不认为有一个标准的方法可以用nestjs 实现这一点。也许使用拦截器,但我不确定。你能在他们的不和谐中问这个吗discord.gg/nestjs

标签: node.js express nestjs


【解决方案1】:

我会尝试的第一件事是使用@Req() param decorator。假设您使用的是 Nests 默认 Express 适配器,那么收到的请求对象是 Express req 对象。

以下内容应该适合您。这篇文章的其余部分只是清理它并使其更“巢”。

import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller()
export class AppController{
  @Get()
  test(@Req() req: Request): string {
   
    req.on('close', () => console.log('Doing something with closed connection'))

    return "Hello, world!"
  }
}

如果你打算在一些控制器方法中重用这个逻辑,那么我也会考虑为它创建一个自定义装饰器:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { Observable } from 'rxjs';
import { Request } from 'express';

export const OnConnectionClosed = createParamDecorator(
  (data: unknown, ctx: ExecutionContext) =>
    new Observable((observer) => {
      const request = ctx.switchToHttp().getRequest<Request>();

      request.on('close', () => observer.complete());
    }),
);

然后像下面这样使用它:

@Controller()
export class AppController{

  @Get()
  test(@OnConnectionClosed() onClosed: Observable<void>): string {
    onClosed.subscribe({
      complete: () => console.log('Connection closed'),
    });

    return 'Hello, world!';
  }
}

这样,您就创建了自己的“Nest”方式来侦听传入请求的关闭事件。

【讨论】:

  • 谢谢,这是一个好方法,但如果它对某人不起作用,请尝试 request.socket.on('close', (e) => { do stuff }) - 这适用于我;我的情况是有人在 FE 上重新加载页面而不是等待请求完成。
【解决方案2】:

Nestjs 有许多不同的组件,它们在请求的生命周期中的不同时间执行。

这些组件的执行顺序如下

NestJs request Life cycle

  • 收到的请求
  • 全局绑定的中间件
  • 模块绑定中间件
  • 全球卫士
  • 控制器保护
  • 路线守卫
  • 全局拦截器(预控制器)
  • 控制器拦截器(预控制器)
  • 路由拦截器(预控制器)
  • 全球管道
  • 控制器管道
  • 布管
  • 路由参数管道
  • 控制器(方法处理程序)
  • 服务(如果存在)
  • 路由拦截器(请求后)
  • 控制器拦截器(请求后)
  • 全局拦截器(请求后)
  • 异常过滤器(路由、控制器、全局)
  • 服务器响应**

您的问题的答案: 我认为应该从以下几点来检测

  • 全局拦截器(请求后)
  • 控制器拦截器(请求后)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2013-02-19
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多