使用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.
}
});
}
源于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
的回调函数中添加了 resolve
和 reject
参数,并在 then
和 catch
中分别调用它们,以便正确地处理异步操作的结果和错误。
请尝试使用修改后的代码并测试运行,看是否能够解决问题。如果问题仍然存在,请提供更多关于错误的详细信息,以便我们进一步帮助您解决问题。