我正在尝试在Android应用程序中使用grpc。
代码的重要部分是:
private val managedChannel: ManagedChannel = ManagedChannelBuilder
.forTarget("misserverurl.com")
.build()
build.gradle 与版本和依赖项:
minSdkVersion 19
implementation "io.grpc:grpc-okhttp:1.26.0"
implementation "io.grpc:grpc-protobuf:1.26.0"
implementation "io.grpc:grpc-stub:1.26.0"
protos似乎还可以,并且该应用程序在没有TLS的情况下工作(.usePlaintext(((
但是我收到此错误:
java.lang.RuntimeException: TLS ALPN negotiation failed with protocols: [grpc-exp, h2]
似乎SSL握手有问题。
奇怪的是,服务器使用带有TLS的BloomRCP工作。
我尝试过使用不同的minSdkVersions,也使用不同的io.grpc.*库版本,并创建一个空的存储库,其中只有原型文件和运行它的基本代码,但没有任何东西,并使用不同的CipherSuite添加.connectionSpec((。
使用Wireshark,我可以看到我发送的TLS版本是1.2,这是正确和预期的(也许它没有使用HTTP2?
有客人吗? 提前感谢!
---------------------------------------------------编辑---------------------------------------------------
查看库,我发现了这种方法:useTransportSecurity((
/**
* Sets the negotiation type for the HTTP/2 connection to TLS (this is the default).
...
*/
@Override
public final OkHttpChannelBuilder useTransportSecurity() { ... }
默认情况下,我们将TLS与HTTP/2一起使用,所以这不是问题...
HTTP/2 在 TLS 期间使用 ALPN 进行协商。客户端发送它支持的协议(在本例中为 grpc-exp 和 h2,又名 http/2(。然后,服务器选择哪个协议,或者不选择。如果未选择任何协议,则唯一的选项是回退到另一个协议(如HTTP/1(或失败。
gRPC 需要 HTTP/2,因此服务器必须通过 ALPN 选择"h2"。错误是没有发生。您的服务器需要支持 HTTP/2。如果您使用的是 TLS 终止符或使用的是 L7 负载均衡器,则必须将其配置为支持 HTTP/2。
之前使用 java 1.8.0_242-b08 时遇到过此问题,升级到 1.8.0_265 后没有问题
最后,这是一个后端问题。 在此之后: https://www.getambassador.io/reference/core/tls/#alpn_protocols alpn_protocol设置如下:
alpn_protocol = h2[, grpc-epx]
它应该在哪里:
alpn_protocol = h2
有了客户端的那个和这个配置,它就奏效了!
private val managedChannel: ManagedChannel = ManagedChannelBuilder
.forTarget("misserverurl.com")
.build()