博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
grpc简介
阅读量:7047 次
发布时间:2019-06-28

本文共 3103 字,大约阅读时间需要 10 分钟。

介绍了Google的序列化反序列化工具protobuf。在protobuf的proto文件中除了可以定义message格式,还有一种类型时service。Google想通过service来实现rpc的功能,但是并没有在protobuf中实现,而是开放给社区这个接口可以自己实现。同时Google开源了一个官方的实现grpc来生成对应的rpc调用

proto定义

首先在proto文件中定义想要的service

syntax = "proto3";option java_package = "blog.proto";message Person{    string my_name=1;}message Result{    string string=1;}service HelloService {     rpc hello(Person) returns (Result) {} }

官方推荐在grpc中使用proto3,上面可以看到定义了一个HelloService,其下定义了hello方法,Person是入参,Result是出参。需要注意的是入参和出参无法使用简单的数据类型不然会报 Expected message type.

编译

proto文件是需要经过protoc来生成对应的开发语言的源码的,在grpc中需要结合使用grpc的插件来实现proto文件中的service生成java服务端/客户端文件。这里沿用

protobuf {    generatedFilesBaseDir = "$projectDir/src/"    plugins {        grpc {            artifact = 'io.grpc:protoc-gen-grpc-java:1.2.0'        }    }    generateProtoTasks {        all()*.plugins {            grpc {}        }    }}

在protobuf的配置中加入grpc的插件并,运行generateProto之后就可以在src/main下看到一个新的grpc目录,这个目录中就是生成的service接口,生成的文件在客户端和服务端都需要。注意,只有service的接口/类会生成在这个目录,其他的message定义还是保持生成在原来的目录。由于grpc目录不是默认的sourceset,所以编译无法找到对应的生成的java文件,不想每次编译都手动增加目录到编译路径,可以在gradle的build文件中将grpc默认加到sourceset中

sourceSets {    main {        java.srcDir 'src/main/grpc'    }}

Server端

在Server端需要我们手动重写service的实现并实现Server来启动服务

//服务端的实现继承生成的ImplBase类public class HelloServiceImpl extends HelloServiceGrpc.HelloServiceImplBase {    @Override    public void hello(blog.proto.ProtoObj.Person request,                      io.grpc.stub.StreamObserver
responseObserver) { System.out.println(request.getMyName()+" calling"); //onNext返回值 responseObserver.onNext(ProtoObj.Result.newBuilder().setString("hello, "+request.getMyName()).build()); //服务结束 responseObserver.onCompleted(); }}//这是一个简单的Server实现public class HelloServer { private int port; private Server server; public HelloServer(int port) throws IOException { this.port=port; //server的builder server=ServerBuilder.forPort(port).addService(new HelloServiceImpl()).build(); //开始服务器 server.start(); System.out.println("Server started, listening on " + port ); } private void blockUntilShutdown() throws InterruptedException { while(true){ server.awaitTermination(); } } public static void main(String[] args) throws Exception { //启动8080端口并block线程 (new HelloServer(8080)).blockUntilShutdown(); }}

之后运行main方法,服务就启动了。

Client端

Client端在生成完java接口后可以构建Stub与服务器通讯

public class HelloClient {    public static void  main(String[] args){        //grpc的channel        ManagedChannel channel=ManagedChannelBuilder.forAddress("127.0.0.1", 8080).usePlaintext(true).build();        //构建服务的stub        HelloServiceGrpc.HelloServiceBlockingStub stub= HelloServiceGrpc.newBlockingStub(channel);        ProtoObj.Person person=ProtoObj.Person.newBuilder().setMyName("World").build();        //调用方法        System.out.println(stub.hello(person).getString());        //关闭channel,不然服务端会报错“远程主机强迫关闭了一个现有的连接。”        channel.shutdown();    }}

之后运行main方法就可以看到输出hello, World

转载于:https://www.cnblogs.com/resentment/p/6714610.html

你可能感兴趣的文章
程序中方法调用的时间
查看>>
Docker命令
查看>>
Java冒泡排序
查看>>
堆和栈最基本的小区别
查看>>
无压力的软件发布之旅
查看>>
十年架构师留下最完整的Java学习路线,学完年薪88W
查看>>
xpath语法
查看>>
未能加载文件或程序集“System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKe...
查看>>
学习路径
查看>>
20172307 2017-2018-2 《程序设计与数据结构》第3周学习总结
查看>>
【算法学习笔记】52.一道题的三种方法..二分答案、动态规划、计算几何 SJTU OJ 1250 BestSubsequence...
查看>>
隐马尔可夫模型(HMM)
查看>>
phonegap入门–2 Android phonegap工程建立
查看>>
《Python核心编程》第二版第六章练习题答案-第二部分
查看>>
选题阶段:课堂展示脚本
查看>>
在Eclipse中安装pydev插件来编写Python代码
查看>>
天球坐标系和地球坐标系
查看>>
二叉树的基础操作(Java)
查看>>
OC 中的block使用
查看>>
织梦安全的思路---未实践
查看>>