具有未加密 HTTP2 连接的 .Net Core 3.1 gRPC 客户端
.Net Core 3.1 gRPC client with unencrypted HTTP2 connection
我正在尝试通过 HTTP 查询一些本地 gRPC 服务 运行。这是我的 net core 3.1 控制台应用程序:
static async Task Main(string[] args)
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://localhost:16050");
var client = new EventService.EventServiceClient(channel);
var reply1 = await client.GetTrackEventAsync(new GetTrackEventRequest { Name = "01Austra14" });
}
但是它抛出了这个错误:
An exception of type 'Grpc.Core.RpcException' occurred in
System.Private.CoreLib.dll but was not handled in user code:
'Status(StatusCode="Internal", Detail="Error starting gRPC call.
HttpRequestException: An error occurred while sending the request.
Http2ConnectionException: The HTTP/2 server sent invalid data on the
connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).",
DebugException="System.Net.Http.HttpRequestException: An error
occurred while sending the request. --->
System.Net.Http.Http2ConnectionException: The HTTP/2 server sent
invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR'
(0x1).
不幸的是,目前我们无法添加 SSL 证书,我们需要暂时使用纯 HTTP(服务应用程序尚未投入生产)。有人知道这里发生了什么吗?
根据 documentation,AppContext.SetSwitch
调用应该足够了。
服务器是 Asp Net Core 3.1 应用程序。 运行 时间:
- 端口 http://*:16050
- 端口 https://*:16150。 这对客户端的回复是正确的但是如上所述,目前只能在本地使用
服务器提供
- Http1 和 Http2
- REST APIs和gRPC APIs在同一个端口
客户正在使用以下软件包
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.17.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.37.0" />
<PackageReference Include="Grpc.Tools" Version="2.37.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
我不能 100% 确定这适用于您的场景(尽管“Http1 和 Http2”表明:它会适用),但是:我已经看到这个问题与正在尝试的非 TLS 端点有关为 HTTP/1 和 HTTP/2 流量提供服务 - 它会变得有点混乱并尝试用 HTTP/1 响应来响应 HTTP/2 请求(TLS 端点不会发生这种情况,由于握手的工作方式不同)。在我的例子中,修复是告诉服务器 只 服务 HTTP/2。这可以在 Kestrel
/ EndPoints
节点下的 appSettings.json 中通过指定 "Protocols": "Http2"
或在 Program.cs 中通过在 listenOptions.Protocols = HttpProtocols.Http2
中指定来完成=14=]打电话。当我想在没有 TLS 的情况下提供 HTTP/1 和 HTTP/2 服务时,我总是不得不使用不同的端口等
我正在尝试通过 HTTP 查询一些本地 gRPC 服务 运行。这是我的 net core 3.1 控制台应用程序:
static async Task Main(string[] args)
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://localhost:16050");
var client = new EventService.EventServiceClient(channel);
var reply1 = await client.GetTrackEventAsync(new GetTrackEventRequest { Name = "01Austra14" });
}
但是它抛出了这个错误:
An exception of type 'Grpc.Core.RpcException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'Status(StatusCode="Internal", Detail="Error starting gRPC call. HttpRequestException: An error occurred while sending the request. Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).", DebugException="System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.Http2ConnectionException: The HTTP/2 server sent invalid data on the connection. HTTP/2 error code 'PROTOCOL_ERROR' (0x1).
不幸的是,目前我们无法添加 SSL 证书,我们需要暂时使用纯 HTTP(服务应用程序尚未投入生产)。有人知道这里发生了什么吗?
根据 documentation,AppContext.SetSwitch
调用应该足够了。
服务器是 Asp Net Core 3.1 应用程序。 运行 时间:
- 端口 http://*:16050
- 端口 https://*:16150。 这对客户端的回复是正确的但是如上所述,目前只能在本地使用
服务器提供
- Http1 和 Http2
- REST APIs和gRPC APIs在同一个端口
客户正在使用以下软件包
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.17.0" />
<PackageReference Include="Grpc.Net.Client" Version="2.37.0" />
<PackageReference Include="Grpc.Tools" Version="2.37.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
我不能 100% 确定这适用于您的场景(尽管“Http1 和 Http2”表明:它会适用),但是:我已经看到这个问题与正在尝试的非 TLS 端点有关为 HTTP/1 和 HTTP/2 流量提供服务 - 它会变得有点混乱并尝试用 HTTP/1 响应来响应 HTTP/2 请求(TLS 端点不会发生这种情况,由于握手的工作方式不同)。在我的例子中,修复是告诉服务器 只 服务 HTTP/2。这可以在 Kestrel
/ EndPoints
节点下的 appSettings.json 中通过指定 "Protocols": "Http2"
或在 Program.cs 中通过在 listenOptions.Protocols = HttpProtocols.Http2
中指定来完成=14=]打电话。当我想在没有 TLS 的情况下提供 HTTP/1 和 HTTP/2 服务时,我总是不得不使用不同的端口等