javascript 运行GRPC拦截器定义中的NestJs服务函数

dgtucam1  于 2023-02-28  发布在  Java
关注(0)|答案(1)|浏览(166)

我想要在grpc拦截器定义、grpc服务客户端注册文件、我的服务模块类中运行一个nestjs服务函数,其中我注册要调用的grpc服务

@Module({
    imports: [
        ConfigModule,
        ClientsModule.registerAsync([
            {
                name: 'tokenvalidator',
                imports: [ConfigModule, ClsModule],

                useFactory: async (configService: ConfigService) => ({
                    transport: Transport.GRPC,
                    options: {
                        package: 'br',
                        protoPath: join(__dirname, '../../protos/tokenvalidator.proto'),
                        url: configService.get('GRPC_TOKEN_VALIDATOR_HOST'),
                        channelOptions: {
                            interceptors: [(options, nextCall) => {
                                new GRPCInterceptor().interceptGrpcCall(options, nextCall)
                            }]
                        }
                    },

                }) as any,

                inject: [ConfigService],
            },

拦截器是在“channelOptions”对象中描述的,在数组“interceptors”内可以传递一个带有params(options,next)的函数典型的中间件函数,问题GRPCInterceptor是一个NestJS服务类

import {InterceptingCall} from "@grpc/grpc-js";
import {Injectable, NestInterceptor, ExecutionContext, CallHandler} from '@nestjs/common';
import {ClsService} from "nestjs-cls";

@Injectable()
export class GRPCInterceptor {

    constructor(
        private readonly cls: ClsService,

    ) {
    }

    interceptGrpcCall(options, nextCall): any {
        const requester:any = {
            start: (metadata, listener, next) => {
                const newListener = {
                    onReceiveMetadata: (metadata, next) => {
                        next(metadata);
                    },
                    onReceiveMessage: (message, next) => {
                        next(message);
                    },
                    onReceiveStatus: (status, next) => {
                        this.cls.set('grpcStatus', status)
                        console.log(this.cls.get("grpcStatus"))
                        console.log('onReceiveStatus');
                        console.log(options?.method_definition?.path);
                        console.log(status);
                        next(status);
                    }
                };
                next(metadata, newListener);
            },
            sendMessage: function (message, next) {
                next(message);
            },
            halfClose: function (next) {
                next();
            },
            cancel: (message, next) => {
                return new InterceptingCall(nextCall(options), requester);

            }
        };
        return new InterceptingCall(nextCall(options), requester);
    }
}

并且它正在等待clsService构造函数参数

error TS2554: Expected 1 arguments, but got 0.

32                                 new GRPCInterceptor().interceptGrpcCall(options, nextCall)
                                   ~~~~~~~~~~~~~~~~~~~~~

  src/GRPCInterceptor.ts:9:9
    9         private readonly cls: ClsService,
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    An argument for 'cls' was not provided.

我知道您不能执行“new NestJSClass().myFunction()",所以问题是如何在模块上下文中运行我的nestjsClass内的函数
我使用clsModule是因为我在运行时有一个带有一些变量的逻辑,所以我使用它,但我不知道如何示例化一个新类并将其传递给nestjs类

toiithl6

toiithl61#

由于GRPCInterceptor是一个提供者类,因此您应该能够像处理ConfigService那样将其提供给inject数组,并使其成为useFactory的一个参数。

@Module({
    imports: [
        ConfigModule,
        ClientsModule.registerAsync([
            {
                name: 'tokenvalidator',
                imports: [ConfigModule, ClsModule],

                useFactory: async (configService: ConfigService, grpcInterceptor: GRPCInterceptor) => ({
                    transport: Transport.GRPC,
                    options: {
                        package: 'br',
                        protoPath: join(__dirname, '../../protos/tokenvalidator.proto'),
                        url: configService.get('GRPC_TOKEN_VALIDATOR_HOST'),
                        channelOptions: {
                            interceptors: [(options, nextCall) => {
                                grpcInterceptor.interceptGrpcCall(options, nextCall)
                            }]
                        }
                    },

                }) as any,

                inject: [ConfigService, GRPCInterceptor],
            },

相关问题