gPRC简介以及Java中使用gPRC实现客户端与服务端通信(附代码下载)_gprc java client ip-程序员宅基地

技术标签: 架构之路  Java  gRpc  

场景

ProtoBuf的介绍以及在Java中使用protobuf将对象进行序列化与反序列化:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108667427

Thrift介绍以及Java中使用Thrift实现RPC示例:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108689413

之前讲过Protobuf以及Thrift,下面介绍GPRC。

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。

实现

gPRC

gRPC  是一个高性能、开源和通用的 RPC 框架,面向移动和 HTTP/2 设计。目前提供 C、Java 和 Go 语言版本,分别是:grpc, grpc-java, grpc-go. 其中 C 版本支持 C, C++, Node.js, Python, Ruby, Objective-C, PHP 和 C# 支持。

gRPC 一开始由 google 开发,是一款语言中立、平台中立、开源的远程过程调用(RPC)系统。

gRPC 基于 HTTP/2 标准设计,带来诸如双向流、流控、头部压缩、单 TCP 连接上的多复用请求等特。这些特性使得其在移动设备上表现更好,更省电和节省空间占用。

 

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

gRPC 默认使用 protocol buffers,这是 Google 开源的一套成熟的结构数据序列化机制。

gRPC的Github:

https://github.com/grpc

gPRC-JAVA:

https://github.com/grpc/grpc-java

Java中实现GRPC通信

IDEA中新建Maven项目,然后来到gRPC-java的官方的github中将示例中的依赖复制到项目中

 

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.32.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.32.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.32.1</version>
        </dependency>
    </dependencies>

因为gRPC是基于protobuf的,同样要将.proto文件编译成代码。

所以按照其github的指示,引入Maven插件

 

    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

至此完整的pom文件代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.badao.grpc</groupId>
    <artifactId>hellogrpc</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.32.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.32.1</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.32.1</version>
        </dependency>
    </dependencies>


    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>1.6.2</version>
            </extension>
        </extensions>
        <plugins>
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.12.0:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.32.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

待导入完成后。

会在右边Maven面板中的Plugins下多出protobuf插件

 

然后就是在项目下新建src/main/proto目录,此插件会去此目录下找proto文件,在此目录下新建Person.proto

syntax = "proto3";

package com.badao.proto;

option optimize_for =SPEED;
option java_package = "com.badao.grpcjava";
option java_outer_classname = "BadaoDataInfo";
option java_multiple_files = true;

service PersonService {
    rpc GetRealNameByUsername(MyRequest) returns (MyResponse) {}
}

message MyRequest {
    string username = 1;
}

message MyResponse {
    string realname = 2;
}

这里的proto文件使用的是proto3的语法,这里的写法可以将github的代码克隆下来,然后参考其grpc-java\examples\src\main\proto

目录下的写法。

这里描述文件的意思就是定义一个接口PersonService,借口内的方法是GetRealNameByUsername,方法参数是自定义请求参数,方法响应是自定义响应。

下面的message就是java中的类,分别是自定义的请求实体和响应实体,以及对应的属性。

然后就是生成代码。

依次双击上面Maven面板插件中的protobuf:complie和protobuf:compile-custom

 

就会在target下生成对应的实体和相关的请求响应通信相关的类。

gRPC服务端搭建

在src/main/java下新建包com,badao.grpcjava,包下新建PersonServiceImpl类使其继承 PersonServiceGrpc.PersonServiceImplBase

然后重写其方法getRealNameByUsername对具体的根据昵称获取真实名字的具体实现。

package com.badao.grpcjava;

import io.grpc.stub.StreamObserver;

public class PersonServiceImpl extends  PersonServiceGrpc.PersonServiceImplBase {
    @Override
    public void getRealNameByUsername(MyRequest request, StreamObserver<MyResponse> responseObserver) {
        System.out.println("接收到的客户端消息为:"+request.getUsername());

        responseObserver.onNext(MyResponse.newBuilder().setRealname("公众号:霸道的程序猿").build());
        responseObserver.onCompleted();
    }
}

然后新建服务端GrpcServer类

package com.badao.grpcjava;

import io.grpc.Server;
import io.grpc.ServerBuilder;

import java.io.IOException;


public class GrpcServer {
    private Server server;

    private void start() throws IOException {
        this.server = ServerBuilder.forPort(8899).addService(new PersonServiceImpl()).build().start();
        System.out.println("GRPC Java服务端启动");

        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            public void run() {
                System.out.println("关闭JVM");
                GrpcServer.this.stop();
            }
        }));

        System.out.println("执行到这里");
    }

    private void stop(){
        if(null!=this.server){
            this.server.shutdown();
        }
    }

    private void awaitTermination() throws InterruptedException {
        if(null!=this.server){
            this.server.awaitTermination();
        }
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        GrpcServer server = new GrpcServer();
        server.start();
        server.awaitTermination();
    }
}

这块的服务端的搭建可以参考gihub上示例代码的grpc-java\examples\src\main\java\io\grpc\examples\helloworld

目录下的服务和客户端的示例代码

 

gRPC客户端的搭建

在上面新建的包下新建GrpcClient客户端类

package com.badao.grpcjava;

import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;

public class GrpcClient {
    public static void main(String[] args) {
        ManagedChannel managedChannel  = ManagedChannelBuilder.forAddress("localhost",8899)
                .usePlaintext().build();
        PersonServiceGrpc.PersonServiceBlockingStub blockingStub = PersonServiceGrpc.newBlockingStub(managedChannel);
        MyResponse myResponse = blockingStub.getRealNameByUsername(MyRequest.newBuilder().setUsername("公众号:霸道的程序猿").build());
        System.out.println(myResponse.getRealname());
    }
}

然后运行服务端的主方法后

 

然后再运行客户端的main方法

 

此时再查看服务端

 

示例代码下载

https://download.csdn.net/download/BADAO_LIUMANG_QIZHI/12874737

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108711541

智能推荐

.net core未能加载程序集解决办法_c# .netcore7.0 加载不了程序集-程序员宅基地

文章浏览阅读1k次。出现问题 运行.net core应用程序,报错未能加载程序集,具体详情如下图所示:分析问题 API接口程序集引用了一个程序集,而这个程序集又引用了其他的程序集,这个时候就存在了间接引用的关系啦,如下图所示:解决问题 重新发布一下被DTO的引用的程序集,然后手工删除一下DTO程序集,重新添加引用就可以重新运行啦,如下图所示: ..._c# .netcore7.0 加载不了程序集

2008-01-10个人-程序员宅基地

文章浏览阅读302次。好几天没折腾硬件了,收块DS3还是P5K-D?或者是加到4G内存?还是换块显卡?呵呵,欲望太多了。房奴呀,现在一个月才有900大洋的生活费,没钱折腾了。还是想收块7900GS, 还要收个T120,呵呵,U120-E太贵了,肯定还要配个YY的风扇,不值。上次的T120成色太差,要是这次换了,就可以不加风扇了。现在用的E2140体质太差,只能350*8,到时再换块板试一下。然后再收对Kings

springboot对于参数的处理,get和post,@GetMapping和@PostMapping_springboot中写get和post接口是的参数用什么注解-程序员宅基地

文章浏览阅读3.3k次。(1)@GetMapping只能通过url传参数。所对应的接口参数只能是用@RequestParam注解或者不注解(2)@PostMapping既可以通过url传参数,也可以通过body传json参数。所对应的接口参数可以有@RequestParam注解,也可以有@RequestBody注解,也可以没有注解。(3)不管是@GetMapping还是@PostMapping,除了@RequestBody注解对应的参数是通过json在body里面传参数外,@RequestParam注解和没有注解都是在ur_springboot中写get和post接口是的参数用什么注解

查询快递物流提前签收的单号,快速分析筛选的方法_快递签收快速比对-程序员宅基地

文章浏览阅读152次。并分析物流,还有很多小伙伴们不知道这种批量查询的方法,下面就以查询快递物流信息,快速分析筛选出提前签收件为例,一起看如何操作吧。此批单号中有提前签收的单号,就会被分析筛选出显示在窗口上。任意双击一个单号查看,物流显示已签收了,但是还有物流动态,说明提前签收分析筛选成功。那么全部查询完成单号物流后,如何快速分析出有提前签收的单号呢?打开左上角的“工具”菜单,用里面的“提前签收分析”功能。全部单号自动发送到主界面上,一行一个,打开“刷新物流”菜单,用“刷新当前页单号”开始查询物流。运行快递批量查询高手软件。_快递签收快速比对

K8S 5G 专有词汇_multiprotocol over frame relay-程序员宅基地

文章浏览阅读2.6k次。5G词汇 导出与导入导出导入Local list of abbreviations(Please note: the list below was created a long time ago, and has been transferred across different web pages over time. It is likely not as updated as the on..._multiprotocol over frame relay

jQuery-Ajax(详解)_jquery.ajax-程序员宅基地

文章浏览阅读2.7w次,点赞77次,收藏419次。安装Web环境Ajax方法需要与Web服务器端进行交互,需要有环境才可正常使用,安装环境的工具包有很多,可以选择自行下载。jQuery中的Ajax在jQuery中,$.Ajax()方法属于最底层的方法,第2层是load(),$.get(),和$.post(),第3层是$.getScript()和$.getJSON()方法。一、 load( ) 方法结构load( url , [data] , [callback] )参数解释捕获.PNG1.1 应用1.1.1首先构建一_jquery.ajax

随便推点

一体机怎么修复音频服务器,多媒体教学一体机没有声音是怎么办?-程序员宅基地

文章浏览阅读7.3k次。教学一体机没有声音怎么办?教学一体机是结合多种传统终端设备为一体的智能设备,可以触摸,可以书写,可以传屏等等功能,主要是于Windows系统和Android系统为载体进行研发的。很多时候,教学一体会出现各种原因导致没有声音,具体原因可以分为软件问题和硬件问题,软件问题包括静音病毒、声卡驱动等,硬件问题包括接口、音响等问题。教学一体机没有声音怎么办?相信我们去查找过很多相关的问题,都没有得到一个准确..._一体机没有声音了怎么恢复

QT学习:Qt 5.11.1+OpenCV (含Contrib)-3.4.3环境搭建_qt5.11.1 licensee-程序员宅基地

文章浏览阅读588次。一、安装CMakeCMake是用于编译的基本工具,其下载地址为:https://cmake.org/download/,下载获得的安装包 文件名为cmake-3.12.3-win64-x64.msi,双击启动安装向导,如图所示:单击“Next”按钮,在如下图所示的左边页面中勾选“I accept the terms in the License Agreement”复 选框接受许可协议,在右边页面中选中“Add CMake to the system PATH for all users”单选按钮添加_qt5.11.1 licensee

【图像隐藏】基于DWT数字水印嵌入+攻击+提取含Matlab源码_信息隐藏攻击matlabe-程序员宅基地

文章浏览阅读483次。1 简介数字水印是一个隐藏信息的行为,它与数字信号的类型(如;图像,歌曲,视频等)有关,它们的概念都是在相应的数字信号里藏有一个信息,然后通过解密来使它们成功分开。水印隐藏的信息与实际的信号的内容有关。水印算法主要分两种:空间域和变换域。空间域就是把信息嵌入到随机选择的图像点中最不重要的象素位置(Least Significant Bits)LSB,这种水印是不可见的;变换域一般是采用扩展频谱通信技术,它的主要技术有(离散傅里叶变换)DFT,(离散余弦变换)DCT 和 DWT,根据这些不同的变换,把数字_信息隐藏攻击matlabe

学习笔记之《高效程序员的45个习惯》-程序员宅基地

文章浏览阅读4.4k次,点赞5次,收藏18次。有本关于敏捷开发方面的书非常不错《高效程序员的45个习惯-敏捷开发修炼之道》,Venkat Subramaniam和Andy Hunt著,该书简短、易读、精炼、深入,深刻且实用。对于想要采用敏捷方法的人很有价值。此书通过常理和经验,阐述了为什么应该在项目中实用敏捷方法。更难得的是,这些行之有效的实战经验,竟然从一本书中得到了。如果能拿这些习惯在项目中一以贯之,肯定会受益匪浅。下本罗列该书这45个习惯,一并列出其中的Key Point._高效程序员的45个习惯

Springboot计算机毕业设计小程序就医管理【附源码】开题+论文+mysql+程序+部署-程序员宅基地

文章浏览阅读789次,点赞17次,收藏12次。首先,通过整合医疗资源,优化就医流程,可以减少患者等待时间,提高医疗服务效率,为患者提供更加便捷、高效的医疗服务。就医管理小程序能够整合医疗资源,优化就医流程,提高医疗服务效率,为患者提供更加便捷、高效的医疗服务。通过实现用户管理、附近医院查询、门诊部管理、检查部管理、住院部管理、药房管理等功能模块,为患者提供挂号预约、门诊报告查询、检查安排查看、药方安排查询等便捷服务;通过本研究的实施,我们预期将开发出一款功能完善、操作便捷的就医管理小程序,为患者提供高效、优质的医疗服务。

联盟鱼的一种说法_联盟鱼lead-程序员宅基地

文章浏览阅读74次。一种是库料,简单的理解为就是通过一些技术手段,一下子可以获取一部分数量的信息,至于这些信息是什么时候存在的不清楚,然后再有测活软件,一一筛选,得到有效利用的,然后再找对应的项目来做。做国外广告联盟的人或者是亚马逊圈里面,再有通道都会接触到这些技术,所谓需不需要吧,最起码是要懂得的。当然这些都是可以通过一定技术来实现的,需要匹配不同的资源,需要哪些数据再去结合就够了。不管国外LEAD也好,还是其他的也罢,言尽于此。还有一种就是所谓的新鲜的,如同去菜市场买菜一样,看到活蹦乱跳的大鲤鱼,这种情况下,叫做鲜鱼。_联盟鱼lead