c++客户端 grpc_gRPC的Java实现

本文介绍了gRPC的基本概念,强调其基于HTTP/2、支持多种开发语言以及使用Protocol Buffers作为IDL的优势。通过一个HelloWorld实例,详细阐述了使用protobuf定义接口和数据类型、编写gRPC服务端和客户端代码的步骤,并展示了Server端和Client端的代码运行结果,完成了一个简单的Java gRPC demo。想要深入学习,可访问gRPC官网。
摘要由CSDN通过智能技术生成
  • 基本概念

       gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。在 gRPC 里,客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

gRPC具有以下特点:

(1)基于 HTTP/2, 继而提供了连接多路复用、Body 和 Header 压缩等机制。可以节省带宽、降低TCP链接次数、节省CPU使用和延长电池寿命等。

(2)支持主流开发语言(C, C++, Python, PHP, Ruby, NodeJS, C#, Objective-C、Golang、Java)

(3)IDL (Interface Definition Language) 层使用了 Protocol Buffers, 非常适合团队的接口设计

f80a4b1ef57d41141f542d07135538de.png

  • HelloWorld实例详解

gRPC的使用通常包括如下几个步骤:

  1. 通过protobuf来定义接口和数据类型

  2. 编写gRPC server端代码

  3. 编写gRPC client端代码

  • 编写helloworld.proto

syntax = "proto3";
option java_multiple_files = true;
option java_package = "com.manong.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";
package helloworld;// The greeting service definition.service Greeter {// Sends a greetingrpc SayHello (HelloRequest) returns (HelloReply) {}
}// The request message containing the user's name.message HelloRequest {string name = 1;}// The response message containing the greetingsmessage HelloReply {string message = 1;}
  • Maven配置

3.12.03.12.01.31.1io.grpcgrpc-bom1.31.1pomimportio.grpcgrpc-protobufio.grpcgrpc-stubio.grpcgrpc-servicesio.grpcgrpc-netty-shadedruntimekr.motd.mavenos-maven-plugin1.6.2org.xolstice.maven.pluginsprotobuf-maven-plugin0.6.1com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}grpc-javaio.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}compilecompile-customorg.apache.maven.pluginsmaven-enforcer-plugin1.4.1enforceenforce

运行maven插件中下面命令,根据proto生成源代码

cd61315459aca6ba282175f89b9532ee.png

项目target下生成如下代码,实际项目上线后可以把该代码copy到对应src下面,把target下面的源码删除掉,这样也不用每次用maven中plugin去再生成代码。

cb606544d9025e87ba5e144adcb6bf93.png

  • Server端代码

import com.manong.grpc.helloworld.GreeterGrpc;
import com.manong.grpc.helloworld.HelloReply;
import com.manong.grpc.helloworld.HelloRequest;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class HostnameServer extends GreeterGrpc.GreeterImplBase {private static final Logger logger = Logger.getLogger(HostnameServer.class.getName());
private final String serverName;
public HostnameServer(String serverName) {if (serverName == null) {
serverName = determineHostname();}this.serverName = serverName;}@Overridepublic void sayHello(HelloRequest req, StreamObserver responseObserver) {
HelloReply reply = HelloReply.newBuilder()
.setMessage("Hello , " + req.getName() + ", from " + serverName)
.build();responseObserver.onNext(reply);responseObserver.onCompleted();}private static String determineHostname() {try {return InetAddress.getLocalHost().getHostName();} catch (IOException ex) {logger.log(Level.INFO, "Failed to determine hostname. Will generate one", ex);}// Strange. Well, let's make an identifier for ourselves.return "generated-" + new Random().nextInt();}public void init() throws Exception {int port = 50051;String hostname = "0.0.0.0";
final Server server = ServerBuilder.forPort(port)
.addService(this)
.build()
.start();System.out.println("Listening on port " + port);Runtime.getRuntime().addShutdownHook(new Thread() {@Overridepublic void run() {server.shutdown();
try {if (!server.awaitTermination(30, TimeUnit.SECONDS)) {server.shutdownNow();server.awaitTermination(5, TimeUnit.SECONDS);}
} catch (InterruptedException ex) {server.shutdownNow();}
}
});server.awaitTermination();}public static void main(String[] args) throws Exception {
HostnameServer hostnameServer = new HostnameServer("grpc server");hostnameServer.init();}
}

运行Server,出现如下输出表示Server已经正常启动

99260961eae0d3718757692832b0bd2a.png

  • Client端代码

import com.manong.grpc.helloworld.GreeterGrpc;
import com.manong.grpc.helloworld.HelloReply;
import com.manong.grpc.helloworld.HelloRequest;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
public class HostnameClient {public static void main(String[] args) {
String target = "localhost:50051";ManagedChannel channel = ManagedChannelBuilder.forTarget(target).usePlaintext().build();
try {
GreeterGrpc.GreeterBlockingStub greeterBlockingStub = GreeterGrpc.newBlockingStub(channel);//传参HelloRequest defaultInstance = HelloRequest.newBuilder().setName("manong").build();HelloReply helloReply = greeterBlockingStub.sayHello(defaultInstance);System.out.println(helloReply.getMessage());} catch (Exception e) {
e.printStackTrace();}
}
}

运行client端代码,出现如下输出,表示调用server服务成功并获得返回值

a58ee55a7fd30fc4681156b9375ab534.png

到此为止,一个完整的基于Java的gRpc demo就完成了。想了解更多可以猛击https://grpc.io/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值