当前位置:网站首页 > Java教程 > 正文

grpc java教程



Java中gRPC的基本教程介绍。

本教程提供了有关使用gRPC的基本Java程序员介绍。

通过遍历此示例,您将学习如何:

  • grpc设计的核心概念。
  • 在.proto文件中定义服务。
  • 使用协议缓冲区编译器生成服务器和客户端代码。
  • 使用Java gRPC API为您的服务编写一个简单的客户端和服务器。

假定您已经阅读了gRPC简介并且熟悉协议缓冲区。请注意,本教程中的示例使用了 proto3协议缓冲区语言的版本:您可以在proto3语言指南中找到更多信息和Java生成的代码指南。

我们的示例是一个简单的路由映射应用程序,它使客户端可以获取有关其路由功能的信息,创建其路由的摘要以及与服务器和其他客户端交换路由信息(例如流量更新)。

借助gRPC,我们可以在一个文件中定义一次服务,并以gRPC支持的任何语言生成客户端和服务器,而这又可以在从大型数据中心内的服务器到您自己的平板电脑的各种环境中运行– gRPC为您处理不同的语言和环境。我们还获得了使用协议缓冲区的所有优点,包括有效的序列化,简单的IDL和轻松的接口更新。

GRPC包含三个不同的层:StubChannelTransport

Stu

Stub层是大多数开发人员都可以接触到的,它为您要适应的任何数据模型/ IDL /接口提供类型安全的绑定。gRPC带有协议缓冲区编译器的插件,该插件可以从文件中生成Stub接口,但是与其他数据模型/ IDL的绑定是容易的并且值得鼓励。

Channel

通道层是传输处理上的抽象,适合于侦听/装饰,并且比存根(Stub)层向应用程序公开更多的行为。对于应用程序框架而言,使用该层来解决诸如日志记录,监视,身份验证等跨领域的问题很容易。

Transport

传输层不费吹灰之力地将字节从导线中取出。它的接口是抽象的,足以允许插入不同的实现。请注意,传输层API被认为是gRPC内部的,并且与包中的核心API相比,其API保证较弱。

gRPC带有三种传输实现:

  1. 基于Netty的传输是基于Netty的主要传输实现 。它适用于客户端和服务器。
  2. 基于OkHttp的传输是基于OkHttp的轻量级传输 。它主要用于Android,并且仅用于客户端。
  3. 进程内传输适用于服务器与客户端处于同一进程中的情况。它对于测试很有用,同时也可以安全地用于生产。

本教程的示例代码在 grpc / grpc-java / examples / src / main / java / io / grpc / examples / routeguide中。要下载示例,请通过运行以下命令在存储库中克隆最新版本:

 

然后将当前目录更改为:

 

我们的第一步(如您从gRPC简介中所知道的)是使用协议缓冲区定义gRPC服务以及方法请求响应类型。 。您可以在grpc-java / examples / src / main / proto / route_guide.proto中看到完整的.proto文件。 。

在此示例中生成Java代码时,我们 在.proto中指定了一个文件选项:

 

这指定了我们要用于生成的Java类的包。如果.proto文件中未提供显式选项,则默认情况下将使用proto软件包(使用“ package”关键字指定)。但是,proto软件包通常不能成为良好的Java包,因为proto软件包不应以反向域名开头。如果我们从此.proto生成另一种语言的代码,则该选项无效。

要定义服务,我们在.proto文件中指定一个名称:

 

然后,在服务定义中定义方法,并指定其请求和响应类型。gRPC允许您定义四种服务方法,所有这些方法都在服务中使用:

  • 一个简单的RPC,客户端使用存根将请求发送到服务器,然后等待响应返回,就像正常的函数调用一样。
     
  • 一个服务器端流RPC,其中客户端发送请求到服务器,并获得一个流中读取消息的序列后面。客户端从返回的流中读取,直到没有更多消息为止。如我们的示例所示,您可以通过 在响应类型之前放置关键字来指定服务器端流方法。
     
  • 一个客户端流传输的RPC,其中客户端将消息写入Point序列,并且将它们发送到服务器,再次使用提供的流。客户端写完消息后,它将等待服务器读取所有消息并返回其响应。您可以通过将关键字放在请求类型之前来指定客户端流方法。
     
  • 一个双向流RPC双方都派出使用读写流的消息序列。这两个流是独立运行的,因此客户端和服务器可以按照自己喜欢的顺序进行读写:例如,服务器可以在写响应之前等待接收所有客户端消息,或者可以先读取一条消息再写入一条消息,或其他一些读写组合。每个流中的消息顺序都会保留。您可以通过 在请求和响应之前放置关键字来指定这种类型的方法。
     

我们的文件还包含用于服务方法中所有请求和响应类型的协议缓冲区消息类型定义-例如,以下是消息类型:

 

接下来,我们需要根据.proto服务定义生成gRPC客户端和服务器接口。我们使用带有特殊gRPC Java插件的协议缓冲区编译器进行此操作。您需要使用 proto3 编译器(同时支持proto2和proto3语法)以生成gRPC服务。

使用Gradle或Maven时,protoc构建插件可以生成必要的代码作为构建的一部分。您可以参考grpc-java自述文件有关如何从您自己的文件生成代码的信息。

以下类是根据我们的服务定义生成的:

  • ,,,和其他含有的所有协议缓存代码来填充,序列化,并检索我们的请求和响应消息的类型。
  • 其中包含(以及一些其他有用的代码):
     
      
    • 服务器要实现 的基类,其中包含服务中定义的所有方法 。
    • 客户端可以用来与服务器对话的存根类。

首先让我们看一下如何创建服务器。如果您只对创建gRPC客户端感兴趣,则可以跳过本节,直接进入创建客户端(尽管您可能仍然会发现它很有趣!)。

使我们的服务发挥作用有两个部分:

  • 覆盖根据我们的服务定义生成的服务基类:完成我们服务的实际“工作”。
  • 运行gRPC服务器以侦听来自客户端的请求并返回服务响应。

您可以在grpc-java / examples / src / main / java / io / grpc / examples / routeguide / RouteGuideServer.java中找到我们的示例服务器。 。让我们仔细看看它是如何工作的。

实施RouteGuide

如您所见,我们的服务器有一个扩展生成的抽象类的类:

 

简单的RPC

实现我们所有的服务方法。首先让我们看一下最简单的方法,该方法仅从客户端获取a ,并从其数据库中的a中返回相应的特征信息。

 

该方法有两个参数:

  • :请求
  • :响应观察者,这是服务器用来调用其响应的特殊接口。

要将我们的回复返回给客户并完成通话,请执行以下操作:

  1. 根据服务定义中的说明,我们构造并填充一个响应对象以返回到客户端。在此示例中,我们使用单独的私有方法进行此操作。
  2. 我们使用响应观察者的方法返回。
  3. 我们使用响应观察者的方法来指定我们已经完成了对RPC的处理。

服务器端流式RPC

接下来,让我们看一下我们的流式RPC。是服务器端的流式RPC,因此我们需要将多个s发送回客户端。

 

像简单的RPC一样,此方法获取一个请求对象(客户端希望在其中找到)和一个响应观察者。

这次,我们获得返回到客户端所需的尽可能多的对象(在这种情况下,我们根据它们是否在我们的请求中从服务的功能集中选择它们),并将每个对象依次写入响应观察器。使用其方法。最后,就像在简单的RPC中一样,我们使用响应观察者的方法来告诉gRPC我们已经完成了响应的编写。

客户端流式RPC

现在,让我们看一些更复杂的东西:客户端流方法,从客户端获取s的流,并返回包含有关其行程的信息的单个流。

 

如您所见,像以前的方法类型一样,我们的方法获得一个 响应观察者参数,但是这次它返回a 供客户端编写其。

在方法主体中,我们实例化了一个匿名对象以返回,其中:

  • 每次客户端将a写入消息流时,都应重写该方法以获取功能和其他信息。
  • 覆盖此方法(在客户端完成写消息时调用)以填充并构建我们的。然后,我们调用我们的方法本身的响应观察者的我们,然后调用它的方法来完成从服务器端调用。

双向流式RPC

最后,让我们看一下双向流式RPC 。

 

与我们的客户端流示例一样,我们都获取并返回了 响应观察器,只是这次我们在客户端仍将消息写入 消息流时通过方法的响应观察器返回值。此处读取和写入的语法与我们的客户端流和服务器流方法完全相同。尽管双方总是会按照对方的写入顺序获得对方的消息,但是客户端和服务器都可以按照任何顺序进行读取和写入-流完全独立地运行。

启动服务器

一旦实现了所有方法,我们还需要启动gRPC服务器,以便客户端可以实际使用我们的服务。以下代码段显示了我们如何为服务执行此操作:

 

如您所见,我们使用构建和启动服务器。

为此,我们:

  1. 使用构建器的方法指定我们要用于侦听客户端请求的地址和端口。
  2. 创建我们的服务实现类的实例, 并将其传递给构建器的方法。
  3. 调用并在构建器上为我们的服务创建并启动RPC服务器。

在本节中,我们将研究为我们的 服务创建一个客户端。您可以在grpc-java / examples / src / main / java / io / grpc / examples / routeguide / RouteGuideClient.java中看到我们完整的示例客户端代码。

Instantiating a stub

要调用服务方法,我们首先需要创建一个存根,或者说,创建两个存根:

  • 阻塞/同步存根:这意味着该RPC调用等待服务器响应,并且将或者返回一个响应或抛出异常。
  • 一个非阻塞/异步存根,它对服务器进行非阻塞调用,在该服务器上异步返回响应。您只能使用异步存根进行某些类型的流式调用。

首先,我们需要为存根创建一个gRPC通道,指定我们要连接的服务器地址和端口:

 

我们使用创建 channel。

现在,我们可以使用channel创建stub,method是使用从.proto生成的RouteGuideGrpc类中提供的newStub和newBlockingStub方法。

 

Calling service method

现在让我们看看我们如何调用我们的服务方法。

简单的RPC

在阻塞存根上调用简单的RPC与调用本地方法一样简单。

 

我们创建并填充一个请求协议缓冲区对象(在本例中为),将其传递给阻塞存根上的方法,然后返回一个 。

如果发生错误,则将其编码为,我们可以从获取 。

服务器端流式RPC

接下来,让我们看一下服务器端对的流式调用,该调用返回一个geo的流:

 

如您所见,它与我们刚刚看过的简单RPC非常相似,除了返回一个,该方法返回一个,客户端可以用来读取所有返回的s ,而不是返回单个。

客户端流式RPC

现在,让事情变得更复杂一些:客户端流方法 ,我们将s流发送到服务器并返回一个。对于这种方法,我们需要使用异步存根。如果您已经阅读了“创建服务器”,那么其中的一些内容可能看起来非常熟悉-异步流式RPC在两侧都以类似的方式实现。

 

如您所见,要调用此方法,我们需要创建一个,实现一个特殊的接口供服务器使用其 响应进行调用。在我们我们:

  • 当服务器将a写入消息流时,重写用于打印返回的信息的方法。
  • 重写该方法(在服务器完成其侧面的调用时调用)以减小a ,我们可以检查该方法以查看服务器是否已完成写入。

然后,将传递给异步存根的 方法,并返回我们自己的请求观察器,以编写 s发送给服务器。一旦完成编写点,就使用请求观察者的方法来告诉gRPC我们已经完成了在客户端的编写。完成后,我们将检查服务器端是否已完成。

双向流式RPC

最后,让我们看一下双向流式RPC 。

 

正如我们的客户端流的例子,我们都get和返回 响应的观察者,但这次我们通过我们的方法的反应派观察员值,而服务器还在写邮件给他们的 消息流。此处读取和写入的语法与我们的客户端流方法完全相同。尽管双方总是会按照对方的写入顺序获得对方的消息,但是客户端和服务器都可以按照任何顺序进行读取和写入-流完全独立地运行。

按照示例目录自述文件中的说明进行操作 构建并运行客户端和服务器。

https://grpc.io/docs/languages/java/quickstart/
https://github.com/grpc/grpc-java/blob/master/README.md
如果觉得写得不好,欢迎指出;如果觉得写得不错,欢迎亲们赞赏。
对卡卡的赞赏

  • 上一篇: java scoket 教程
  • 下一篇: java压缩解压教程
  • 版权声明


    相关文章:

  • java scoket 教程2025-01-24 11:10:04
  • java语言案例教程2025-01-24 11:10:04
  • java模板使用教程2025-01-24 11:10:04
  • 微信二次开发java视频教程合集2025-01-24 11:10:04
  • java写ai教程2025-01-24 11:10:04
  • java压缩解压教程2025-01-24 11:10:04
  • java自学教程52025-01-24 11:10:04
  • java座椅安装教程2025-01-24 11:10:04
  • java自学手册教程2025-01-24 11:10:04
  • java455集教程2025-01-24 11:10:04