【发布时间】:2020-06-18 16:10:27
【问题描述】:
我使用 C# 在 dotnet core 3.1 中定义和实现了一个 gRPC 服务。我有一个这样定义的流调用:
service MyService {
rpc MyStreamingProcedure(Point) returns (stream ResponseValue);
}
在服务中生成
public virtual global::System.Threading.Tasks.Task MyStreamingProcedure(global::MyService.gRPC.Point request, grpc::IServerStreamWriter<global::MyService.gRPC.ResponseValue> responseStream, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
在我的服务中,它是通过覆盖这个来实现的:
public override async Task MyStreamingProcedure(Point request, IServerStreamWriter<ResponseValue> responseStream, ServerCallContext context)
{
/* magic here */
}
我在 docker 容器中有这个建筑,当我在 localhost 上运行它时,它运行完美:
docker run -it -p 8001:8001 mycontainerregistry.azurecr.io/myservice.grpc:latest
现在问题来了。当我在 Azure 容器实例中运行它并使用公共 IP 地址调用客户端时,调用失败并显示
未处理的异常。 Grpc.Core.RpcException:状态(StatusCode=未实现,详细信息=“方法未实现。”) 在 Grpc.Net.Client.Internal.HttpContentClientStreamReader`2.MoveNextCore(CancellationToken cancelToken)
它似乎没有看到覆盖并且正在基类中运行该过程。使用在公共 ACI 中运行的容器,对同一 gRPC 服务的一元调用可以正常工作。为什么流式调用在 localhost 和通过公共 IP 地址运行时会表现不同?
【问题讨论】:
-
如何部署镜像?你介意和我分享这张照片吗?
-
除非您的 RPC 寿命很长,否则流式传输与一元 RPC 不太可能产生影响。在 HTTP2 协议层,两种 RPC 看起来是一样的。我认为你的代码中有一些非常简单的东西你错过了。我认为您也可能不小心与旧版本的后端交谈,该版本没有您认为的代码。
-
你解决过这个问题吗?在本地机器上的 docker 中运行时,我得到了相同的行为。
-
自己发现了错误。我在一个单独的项目中有原始文件。该项目使用 Grpc.Tools 以及服务器。这两个需要匹配版本(Grpc.Tools被Grpc.AspNetCore间接使用)。
标签: docker .net-core grpc azure-container-instances