你看我像是会的样子吗? 2023-06-27 16:52 采纳率: 57.1%
浏览 9
已结题

midwayjs Koa3调用c#的grpc服务一直报错provider response timeout in 1000?

使用midwayjs Koa3调用c#的grpc服务一直报错provider response timeout in 1000,第一次写这种,检查了很多地方都没检查出问题,请大家帮忙看一下,感激不尽!

1.下面是调用服务的代码

@Processor('zktecoqu',{removeOnFail: false,delay: 3000}) 
export class ZktecoProcessor implements IProcessor {
    @Inject()
    grpcClients: Clients;

    greeterService: greet.ZKTecoClient;

    @Init()
    async init() {
        // 赋值一个服务实例
        this.greeterService = this.grpcClients.getService<greet.ZKTecoClient>(
            'greet.ZKTeco'
        );
    }

    async execute(data: any) {
        const c = this.greeterService.connect({ timeout: 60000 });
        const datas = {
            id: 'zhls3c',
            hostname: '10.100.200.201',
            port: 4370,
            password: 244525,
            action: 0
        }
        const result = await new Promise<number>((resolve, reject) => {
            // 第一次调用和返回
            c.sendMessage(datas)
                .then(res => {
                    console.log('res',res)
                })
                .catch(err => console.error('err',err));
        });
        console.log('connectresult', result)
    }
}

2.下面是c#服务端的代码

 public override Task Connect(IAsyncStreamReader<ConnectParam> requestStream, IServerStreamWriter<ConnectStatus> responseStream, ServerCallContext context)
        {

           
                Console.WriteLine(requestStream);
                // 先獲取一下設備狀態
                foreach (var kvp in instances)
                {
                    int dwErrorCode = 0;
                    kvp.Value.GetConnectStatus(ref dwErrorCode);
                    if (dwErrorCode == 0)
                    {
                        var status = new ConnectStatus();
                        status.Id = kvp.Key;
                        status.Connected = dwErrorCode == 0;
                        status.Message = dwErrorCode == 0 ? null : $"error code: {dwErrorCode}";
                        responseStream.WriteAsync(status);
                    }
                }

                using (var subscription = statusSubject.Subscribe(res =>
                {
                    responseStream.WriteAsync(res);
                }))
                {
                    // 在客戶端取消請求的時候,停止訂閱
                    context.CancellationToken.Register(() =>
                    {
                        subscription.Dispose();
                    });
                }

                return Task.Run(async () =>
                {
                    await foreach (var message in requestStream.ReadAllAsync())
                    {
                        switch (message.Action)
                        {
                            case 0:
                                var ins = new zkemkeeper.CZKEMClass();
                                if (message.Password != null)
                                {
                                    ins.SetCommPassword((int)message.Password);
                                }
                                ins.Connect_Net(message.Hostname, (int)message.Port);
                                break;



                        }
                        // Process request.
                    }
                });


        }
  • 写回答

1条回答 默认 最新

  • 自在猫先生 2023-06-28 10:20
    关注

    源于chatGPT仅供参考

    根据您提供的代码,问题可能出在以下几个方面:
    
    1. 超时设置:在调用 gRPC 服务的 `c.sendMessage` 方法时,您传递了 `{ timeout: 60000 }` 参数。这个参数表示超时时间为 60 秒。如果服务端在此时间内没有返回响应,会导致超时错误。请确保服务端能够在指定的时间内返回响应。
    
    2. 异常处理:在客户端调用 `c.sendMessage` 方法后,您使用 `.then` 和 `.catch` 来处理成功和失败的情况。但是,在 `.catch` 中只打印了错误日志,并没有对 Promise 进行 reject 操作。这可能导致在发生异常时,Promise 没有被正确地处理,并且无法捕获超时错误。您可以尝试在 `.catch` 中添加 `reject(err)` 来处理异常情况。
    
    3. 流式处理:在 C# 服务端的 `Connect` 方法中,您使用了 `responseStream.WriteAsync(status)` 来写入连接状态。但是在处理请求的循环中,没有使用 `responseStream.WriteAsync` 来写入其他响应。这可能导致客户端在收到第一个响应后不再继续等待其他响应,从而导致超时错误。请确保在适当的位置使用 `responseStream.WriteAsync` 发送所有需要的响应。
    
    另外,请确保您的 gRPC 服务端已经正确启动,并且客户端和服务端之间的网络连接正常。
    
    如果问题仍然存在,请提供更多关于错误的详细信息,例如完整的错误日志或堆栈跟踪。这将有助于进一步分析和解决问题。
    
    

    根据您提供的代码,我帮您调整了一些问题,并添加了一些注释说明。请参考以下修改后的代码:

    @Processor('zktecoqu', { removeOnFail: false, delay: 3000 })
    export class ZktecoProcessor implements IProcessor {
      @Inject()
      grpcClients: Clients;
    
      greeterService: greet.ZKTecoClient;
    
      @Init()
      async init() {
        // 赋值一个服务实例
        this.greeterService = this.grpcClients.getService<greet.ZKTecoClient>('greet.ZKTeco');
      }
    
      async execute(data: any) {
        const c = this.greeterService.connect();
        const datas = {
          id: 'zhls3c',
          hostname: '10.100.200.201',
          port: 4370,
          password: 244525,
          action: 0,
        };
    
        // 增加 Promise 的 resolve 和 reject 参数
        const result = await new Promise<number>((resolve, reject) => {
          // 第一次调用和返回
          c.sendMessage(datas)
            .then((res) => {
              console.log('res', res);
              // 调用 resolve 将结果传递给 Promise
              resolve(res);
            })
            .catch((err) => {
              console.error('err', err);
              // 调用 reject 将错误传递给 Promise
              reject(err);
            });
        });
    
        console.log('connectresult', result);
      }
    }
    

    在上述代码中,我移除了 c.sendMessage 方法的 { timeout: 60000 } 参数,以便使用默认的超时设置。

    同时,在 execute 方法中,我将 new Promise 的回调函数中添加了 resolvereject 参数,并在 thencatch 中分别调用它们,以便正确地处理异步操作的结果和错误。

    请尝试使用修改后的代码并测试运行,看是否能够解决问题。如果问题仍然存在,请提供更多关于错误的详细信息,以便我们进一步帮助您解决问题。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 12月20日
  • 已采纳回答 12月12日
  • 创建了问题 6月27日

悬赏问题

  • ¥15 请把下列每一行代码完整地读懂并注释出来
  • ¥15 pycharm运行main文件,显示没有conda环境
  • ¥15 易优eyoucms关于二级栏目调用的问题
  • ¥15 寻找公式识别开发,自动识别整页文档、图像公式的软件
  • ¥15 为什么eclipse不能再下载了?
  • ¥15 编辑cmake lists 明明写了project项目名,但是还是报错怎么回事
  • ¥15 关于#计算机视觉#的问题:求一份高质量桥梁多病害数据集
  • ¥15 特定网页无法访问,已排除网页问题
  • ¥50 如何将脑的图像投影到颅骨上
  • ¥15 提问一个关于vscode相关的环境配置问题,就是输入中文但是显示不出来,代码在idea可以显示中文,但在vscode不行,不知道怎么配置环境