You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python调用gRPC .NET服务遇HTTP/2解析失败,单端口兼容JSON转码咨询

问题

我们正在试验gRPC与JSON转码技术,以支持Delphi客户端调用服务,技术栈包含Python 3.10与.NET服务。使用.NET 7搭配Microsoft.AspNetCore.Grpc.JsonTranscoding包实现JSON转码,为测试定义了三个对应不同HTTP协议版本的端口:

webBuilder.UseKestrel(kestrelOptions =>
{
    kestrelOptions.ListenAnyIP(5000, listenOptions =>
    {
        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1;
    });
    kestrelOptions.ListenAnyIP(5001, listenOptions =>
    {
        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http2;
    });
    kestrelOptions.ListenAnyIP(5002, listenOptions =>
    {
        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
    });
});

各端口测试情况:

  • 5000端口:gRPC无法工作,但可通过JSON转码调用服务
  • 5001端口:Python与.NET7客户端均可正常使用gRPC,但JSON转码无法工作
  • 5002端口:仅.NET7客户端可使用gRPC,JSON转码正常;Python客户端触发如下错误:
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
    status = StatusCode.UNAVAILABLE
    details = "failed to connect to all addresses; last error: UNAVAILABLE: ipv4:127.0.0.1:5000: Failed parsing HTTP/2"
    debug_error_string = "UNKNOWN:failed to connect to all addresses; last error: UNAVAILABLE: ipv4:127.0.0.1:5000: Failed parsing HTTP/2 {created_time:"2022-11-08T07:07:49.2047503+00:00", grpc_status:14}"
>

Python客户端不支持协议协商,请问是否有办法在单端口同时启用JSON转码与两种协议?

使用版本:
-.NET 7.0.100-rc.2.22477.23
-Microsoft.AspNetCore.Grpc.JsonTranscoding 7.0.0-rc.2.22476.2
-Python 3.10.1
-grpcio 1.50.0


解决方案

要在单端口同时支持JSON转码(依赖HTTP/1.1)和gRPC(依赖HTTP/2),并兼容Python客户端,可通过以下两种方案实现:

方案一:配置TLS启用ALPN协议协商

这是gRPC官方推荐的跨客户端兼容方案,通过TLS的ALPN(应用层协议协商)机制,Kestrel可自动区分HTTP/1.1和HTTP/2请求。修改Kestrel配置如下:

webBuilder.UseKestrel(kestrelOptions =>
{
    kestrelOptions.ListenAnyIP(5003, listenOptions =>
    {
        listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
        // 配置证书,开发环境可使用dotnet dev-certs生成的证书
        listenOptions.UseHttps("dev-cert.pfx", "password");
    });
});

配置TLS后,Python的grpcio客户端会自动通过ALPN协商使用HTTP/2协议,解决解析错误问题,同时JSON转码的HTTP/1.1请求也能正常处理。

方案二:Python客户端强制使用明文HTTP/2(无TLS场景)

如果暂时无法配置TLS,可在Python客户端连接时强制指定h2c(明文HTTP/2)协议,绕过协议协商步骤:

import grpc

# 创建通道时强制使用明文HTTP/2
channel = grpc.insecure_channel(
    "127.0.0.1:5002",
    options=[
        ("grpc.http_protocol", "h2c"),
        ("grpc.default_authority", "localhost")
    ]
)

此配置下,Python客户端会直接发送HTTP/2请求,与配置为Http1AndHttp2的Kestrel端口兼容,同时JSON转码功能不受影响。

验证效果

无论采用哪种方案,配置完成后单端口均可同时支持:

  • Delphi客户端通过JSON转码(HTTP/1.1)调用服务
  • .NET客户端通过gRPC(HTTP/2)调用服务
  • Python客户端通过gRPC(HTTP/2)调用服务

内容的提问来源于stack exchange,提问作者KlemensE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 22:00:57