gRPC试用

Posted 路上的阿鹏哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gRPC试用相关的知识,希望对你有一定的参考价值。

官网 https://www.grpc.io/

gRPC 官方文档中文版 http://doc.oschina.net/grpc

QUICK START

java  

https://www.grpc.io/docs/quickstart/java/

go  

https://www.grpc.io/docs/quickstart/go/

 

文章以一个Java服务端,一个go客户端和一个Java客户端做示例。


pb文件


syntax = "proto3";
option go_package = "com/grpc/helloworld";option java_multiple_files = false;option java_package = "com.grpc.helloworld";option java_outer_classname = "HelloWorldProto";
package helloworld;
// The greeting service definition.service Greeter { // Sends a greeting rpc 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;}

目录结构



使用Golang实现sever端需要安装的组件 安装下面两个插件需要访问google.com


go get -u github.com/grpc/grpc-go//通讯组件 go get -u github.com/golang/protobuf/protoc-gen-go

执行命令 生成文件 


protoc -I ./ helloworld.proto --go_out=plugins=grpc:go

gRPC试用

Go 客户端代码


package mainimport ( "context" "log" "os" "time" "google.golang.org/grpc" pb "test/grpc/pb")const ( address = "localhost:50052" defaultName = "阿鹏哥")func main() { conn, err := grpc.Dial(address, grpc.WithInsecure(), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) name := defaultName if len(os.Args) > 1 { name = os.Args[1] } ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage())}


go 服务端代码,仅做示例,没有运行。


package main
import ( pb "test/grpc/pb" "context" "log" "net" "google.golang.org/grpc")const ( port = ":50051")type server struct { pb.UnimplementedGreeterServer}
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", in.GetName()) return &pb.HelloReply{Message: "你好 " + in.GetName()}, nil}
func main() { lis, err := net.Listen("tcp", port) if err != nil { log.Fatalf("failed to listen: %v", err) } s := grpc.NewServer() pb.RegisterGreeterServer(s, &server{}) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) }}


1 生成pb使用的Java文件,没有使用ide的插件,生成的文件手动拷贝到Java工程中protoc --java_out=java helloworld.proto2 生成 GreeterGrpc.java 文件 通讯需要用protoc --plugin=protoc-gen-grpc-java=/Users/luo/kj/protoc-gen-grpc-java --grpc-java_out=java helloworld.proto


java 目录结构




Java 服务端代码


package com.tvm.test;import com.grpc.helloworld.GreeterGrpc;import com.grpc.helloworld.HelloWorldProto;import io.grpc.*;import io.grpc.stub.StreamObserver;import java.io.IOException;import java.util.concurrent.TimeUnit;import java.util.logging.Level;import java.util.logging.Logger;public class HelloWorldServer { private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName()); private Server server; private void start() throws IOException { /* The port on which the server should run */ int port = 50052; server = ServerBuilder.forPort(port) .addService(new GreeterImpl()) .build() .start(); logger.info("Server started, listening on " + port); Runtime.getRuntime().addShutdownHook(new Thread() { @Override public void run() { // Use stderr here since the logger may have been reset by its JVM shutdown hook. System.err.println("*** shutting down gRPC server since JVM is shutting down"); try { HelloWorldServer.this.stop(); } catch (InterruptedException e) { e.printStackTrace(System.err); } System.err.println("*** server shut down"); } }); } private void stop() throws InterruptedException { if (server != null) { server.shutdown().awaitTermination(30, TimeUnit.SECONDS); } } /** * Await termination on the main thread since the grpc library uses daemon threads. */ private void blockUntilShutdown() throws InterruptedException { if (server != null) { server.awaitTermination(); } } /** * Main launches the server from the command line. */ public static void main(String[] args) throws IOException, InterruptedException { final HelloWorldServer server = new HelloWorldServer(); server.start(); server.blockUntilShutdown(); }
static class GreeterImpl extends GreeterGrpc.GreeterImplBase { @Override public void sayHello(HelloWorldProto.HelloRequest req, StreamObserver<HelloWorldProto.HelloReply> responseObserver) { System.out.println("java sayHello:"+req.getName()); HelloWorldProto.HelloReply reply = HelloWorldProto.HelloReply.newBuilder().setMessage("java 你好 " + req.getName()).build(); responseObserver.onNext(reply); responseObserver.onCompleted(); } }}


java 客户端代码


package com.tvm.test;import com.grpc.helloworld.GreeterGrpc;import com.grpc.helloworld.HelloWorldProto;import io.grpc.Channel;import io.grpc.ManagedChannel;import io.grpc.ManagedChannelBuilder;import io.grpc.StatusRuntimeException;import java.util.concurrent.TimeUnit;import java.util.logging.Level;import java.util.logging.Logger;public class HelloWorldClient { private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
private final GreeterGrpc.GreeterBlockingStub blockingStub;
public HelloWorldClient(Channel channel) { // 'channel' here is a Channel, not a ManagedChannel, so it is not this code's responsibility to // shut it down.
// Passing Channels to code makes code easier to test and makes it easier to reuse Channels. blockingStub = GreeterGrpc.newBlockingStub(channel); }
/** Say hello to server. */ public void greet(String name) { logger.info("Will try to greet " + name + " ..."); HelloWorldProto.HelloRequest request = HelloWorldProto.HelloRequest.newBuilder().setName(name).build(); HelloWorldProto.HelloReply response; try { response = blockingStub.sayHello(request); } catch (StatusRuntimeException e) { logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus()); return; } logger.info("Greeting: " + response.getMessage()); } public static void main(String[] args) throws Exception { String user = "world"; // Access a service running on the local machine on port 50051 String target = "localhost:50052"; // Allow passing in the user and target strings as command line arguments if (args.length > 0) { if ("--help".equals(args[0])) { System.err.println("Usage: [name [target]]"); System.err.println(""); System.err.println(" name The name you wish to be greeted by. Defaults to " + user); System.err.println(" target The server to connect to. Defaults to " + target); System.exit(1); } user = args[0]; } if (args.length > 1) { target = args[1]; }
// Create a communication channel to the server, known as a Channel. Channels are thread-safe // and reusable. It is common to create channels at the beginning of your application and reuse // them until the application shuts down. ManagedChannel channel = ManagedChannelBuilder.forTarget(target) // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid // needing certificates. .usePlaintext() .build(); try { HelloWorldClient client = new HelloWorldClient(channel); client.greet(user); } finally { // ManagedChannels use resources like threads and TCP connections. To prevent leaking these // resources the channel should be shut down when it will no longer be used. If it may be used // again leave it running. channel.shutdownNow().awaitTermination(5, TimeUnit.SECONDS); } }}


以Java为服务端,go和Java两个客户端实现grpc通讯

 

运行Java服务端代码

输出 INFO: Server started, listening on 50052

运行 Java 客户端代码

输出  INFO: Greeting: java 你好 world

运行 go 客户端代码

输出  2020/05/25 13:21:58 Greeting: java 你好 阿鹏哥





以上是关于gRPC试用的主要内容,如果未能解决你的问题,请参考以下文章

使用Envoy将gRPC转码为HTTP/JSON

Android 片段复制

Grpc对象转proto代码工具

从源代码安装 grpc 时出现“make: protoc: Command not found”

protoc生成gRPC代码和HTTP网关代码

protoc生成gRPC代码和HTTP网关代码