当前位置: 首页 > 知识库问答 >
问题:

使用基于Java的Grpc服务器和基于C#的客户端时出现传输失败错误

车胤运
2023-03-14

我正在使用spring boot(2.2.2)和Grpc server spring boot starter java库开发一个基于java的Grpc服务器。我的客户端应用程序是一个C#应用程序(netcoreapp3.1)。这两个应用程序都在我的笔记本电脑上运行。

这是我的原始文件

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.honeywell.EOM.SystemAPI.webapi.web.grpc.service";
//option java_outer_classname = "TestProto";

service Simple {
    rpc GetData (Empty) returns (Data) {
    }
}

message Empty {

}

message Data {
    string name = 1;
}

这是服务代码

@GrpcService
public class TestService extends SimpleGrpc.SimpleImplBase {
    @Override
    public void getData(Empty request, StreamObserver<Data> responseObserver) {
        Data data = Data.newBuilder().setName("Somename").build();
        responseObserver.onNext(data);
        responseObserver.onCompleted();
    }
}

我首先用这个工具测试了服务器

该服务与此客户端工具配合使用效果良好。

然而,当我使用C#客户端测试时,我得到了这个错误

io.grpc.netty.shaded.io.grpc.netty.NettyServerTransport notifyTerminated
INFO: Transport failed
io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception: HTTP/2 client preface string missing or corrupt. Hex dump for received bytes: 16030100b6010000b203035e95b0402c6320969d3d5fba04
    at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2Exception.connectionError(Http2Exception.java:103)
    at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.readClientPrefaceString(Http2ConnectionHandler.java:306)
    at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler$PrefaceDecoder.decode(Http2ConnectionHandler.java:239)
    at io.grpc.netty.shaded.io.netty.handler.codec.http2.Http2ConnectionHandler.decode(Http2ConnectionHandler.java:438)
    at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:505)
    at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:444)
    at io.grpc.netty.shaded.io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:283)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
    at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
    at io.grpc.netty.shaded.io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
    at io.grpc.netty.shaded.io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931)
    at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
    at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700)
    at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)
    at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)
    at io.grpc.netty.shaded.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)
    at io.grpc.netty.shaded.io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)
    at io.grpc.netty.shaded.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.grpc.netty.shaded.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)

C#客户端代码在这里

using var channel = GrpcChannel.ForAddress("https://localhost:9090");
var client = new Simple.SimpleClient(channel);
var reply = client.GetData(new Empty { });

我做错了什么?这是公开缺陷吗?

共有2个答案

钱和安
2023-03-14

错误消息报告收到的字节(十六进制):

16030100b6010000b203035e95b0402c6320969d3d5fba04

三个起始字节160301看起来像TLS握手。服务器可能处于纯文本模式,客户端正在使用TLS。

要在客户端上使用纯文本,请使用“http”:

using var channel = GrpcChannel.ForAddress("http://localhost:9090");

编辑:此答案的代码示例已损坏;它不能正确地启用纯文本

姚雅珺
2023-03-14

正如Eric Anderson的回答所述,客户确实在使用TLS。

用于gRPC的. NET Core客户端在与不安全(非TLS)服务器通信时需要额外配置(从. NET Core 3.1开始)。

// This switch must be set before creating the GrpcChannel/HttpClient.
AppContext.SetSwitch(
    "System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport", true);

using var channel = GrpcChannel.ForAddress("http://localhost:9090");
var client = new Simple.SimpleClient(channel);
var reply = client.GetData(new Empty { });
 类似资料:
  • 我使用Spring Boot开发了这个websocket服务器。服务器与基于js的客户机配合得很好。 控制器: 这是服务器端。现在,对于客户机,我已经创建了一个@ClientEndpoint,当我连接到URI“ws://localhost:8080/spring-mvc-java/chat”时,我能够建立一个连接,并且可以看到@ClientEndpoint的@OnOpen回调被触发。 但是,use

  • 我的程序基本上是: > 客户端向服务器发送字符串, 基于这个字符串,服务器正在创建一个ArrayList, ArrayList 被发送回客户端。 这里失败的是: 客户端发送字符串后,服务器会收到它,并且不执行任何其他操作。在这段时间里,客户端继续工作并得到一个空指针。 客户端: } 服务器端:

  • 问题内容: 好吧,我正在尝试用Java实现ftp服务器和ftp客户端。我正在尝试从服务器接收文件。以下是代码行。我能够实现服务器与客户端之间的连接,但是也无法将文件名发送到服务器。谁能指导我这种方法是否正确,请提出正确的建议。 服务器的实现: 客户实施: 问题答案: 上述问题的答案是: FTP客户端: FTP服务器:

  • 本文向大家介绍PHP基于socket实现客户端和服务端通讯功能,包括了PHP基于socket实现客户端和服务端通讯功能的使用技巧和注意事项,需要的朋友参考一下 本文主要介绍了PHP基于socket实现的简单客户端和服务端通讯功能,可实现服务端接收客户端发送的字符串进行翻转操作后返回客户端的功能,需要的朋友可以参考下 服务端: 客户端: 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多

  • 我们需要在托管Windows环境中为富客户端实现桌面SSO(一些Vista机器,一些带有Win 2008 Citrix后端的Citrix客户端)。 富客户机(用C/C编写)使用SOAP web服务连接到服务器。服务器是运行在JBoss EAP上的Java应用程序。用户数据存储在Microsoft ActiveDirectory中。ADFS 2.0不适用于我们。富客户端不使用Internet Exp

  • 本文向大家介绍Java基于socket实现的客户端和服务端通信功能完整实例,包括了Java基于socket实现的客户端和服务端通信功能完整实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java基于socket实现的客户端和服务端通信功能。分享给大家供大家参考,具体如下: 以下代码参考马士兵的聊天项目,先运行ChatServer.java实现端口监听,然后再运行ChatClient.j