grpc简介

gRPC (gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/2 协议传输。(摘自知乎:https://zhuanlan.zhihu.com/p/389328756)

功能点

  • 跨平台
  • 序列化
  • 流式数据传输

操作环境

  • 系统:ubuntu 18.04
  • 架构:linux-x86_64
  • 环境:JDK8 maven idea
  • 仓库:阿里云maven

环境准备

Protobuf

Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准。他们用于 RPC 系统和持续数据存储系统。提供一个具有高效的协议数据交换格式工具库(类似Json)。
但相比于Json,Protobuf有更高的转化效率,时间效率和空间效率都是JSON的3-5倍。
可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。目前提供了 C++、Java、Python 、OC、Swift等语言的 API。总只一句话就是很好,支持多平台且与语言无关。(https://www.jianshu.com/p/a24c88c0526a)

简单理解:protobuf是将后缀名为.proto的文件编译成各类语言API的编译工具

安装Protobuf

执行命令:

sudo apt  install protobuf-compiler

查看版本

protoc --version

libprotoc 3.0.0

创建项目

项目结构

在这里插入图片描述

  • grpc为maven父项目。
  • grpc-lib为maven子项目,用于生成由protobuf编译的接口API。
  • grpc-server为服务端SpringBoot子项目,负责实现接口功能。
  • grcp-client为客户端Springboot子项目,负责调用服务端进行返回。
    在这里插入图片描述

父项目构建

  1. 选择一个空的maven项目
    在这里插入图片描述
    在这里插入图片描述
  2. 删除src,使之成为一个空的父项目,这里面项目名为grpc-test,后续会使用grpc代替
    在这里插入图片描述
  3. 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.nces</groupId>
    <artifactId>grpc</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <!--    声明模块,可写不写,创建子模块的时候会自动引入,没有引入再写-->
    <modules>
        <module>grpc-lib</module>
        <module>grpc-client</module>
        <module>grpc-server</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <!--        grpc版本-->
        <grpc-version>1.43.1</grpc-version>
        <!--        service和client要使用的lib版本-->
        <lib-version>1.0-SNAPSHOT</lib-version>
        <!--        netty版本-->
        <netty-version>4.1.65.Final</netty-version>
        <!--        Springboot版本-->
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
        <!--        Springboot-grpc版本,用于server服务注解使用-->
        <grpc-spring-boot-starter.version>3.0.0</grpc-spring-boot-starter.version>
        <!--        maven构建工具版本-->
        <maven-plugin-version>3.8.1</maven-plugin-version>
        <!--        lombok-->
        <lombok-version>1.18.16</lombok-version>
    </properties>

    <!--    使用dependencyManagement声明得到依赖子模块不需要再进行版本指定,直接通过父模块指定即可,以此实现依赖的统一管理,防止出现依赖冲突-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.nces</groupId>
                <artifactId>grpc-lib</artifactId>
                <version>${lib-version}</version>
            </dependency>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-netty</artifactId>
                <version>${grpc-version}</version>
            </dependency>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-protobuf</artifactId>
                <version>${grpc-version}</version>
            </dependency>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-stub</artifactId>
                <version>${grpc-version}</version>
            </dependency>
            <dependency>
                <groupId>io.netty</groupId>
                <artifactId>netty-common</artifactId>
                <version>${netty-version}</version>
            </dependency>
            <dependency>
                <groupId>io.github.lognet</groupId>
                <artifactId>grpc-spring-boot-starter</artifactId>
                <version>${grpc-spring-boot-starter.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok-version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>

子模块构建-lib接口API

模块结构

模块结构
在这里插入图片描述

├── pom.xml
└── src
└── main
├── java
│ └── GetClassifier.java 获取架构工具类,后续使用会详述
└── proto
└── HelloWorld.proto 用于生成接口proto文件

创建步骤

  1. 创建一个maven子项目
    创建成功后子项目会引入父项目的坐标,同时,父项目会自动引入模块。如果没有,可以手动写进去

子项目
在这里插入图片描述
父项目在这里插入图片描述
2.引入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">
    <parent>
        <artifactId>grpc</artifactId>
        <groupId>com.nces</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>
    <artifactId>grpc-lib</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
<!--        架构信息,后续会将怎么获取-->
        <os.detected.classifier>linux-x86_64</os.detected.classifier>
    </properties>

    <dependencies>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-common</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--配置protobuf插件 可参阅https://github.com/grpc/grpc-java-->
            <plugin>
                <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>0.6.1</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:3.19.1:exe:${os.detected.classifier}</protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.43.1:exe:${os.detected.classifier}</pluginArtifact>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-plugin-version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>
  1. 获取架构信息
    写一个类,长期放在java文件夹下,方便其他人获取架构信息时直接调用
    /grpc/grpc-lib/src/main/java
/**
 * @author Xi Peng
 * @Description
 * @createTime 2021年12月29日 17:33:00
 */
public class GetClassifier {
    public static void main(String[] args) {
        System.out.println(System.getProperty("os.name"));
        System.out.println(System.getProperty("os.arch"));
    }
}

执行一下,得到结果

Linux
amd64

打开网站
查看架构关系
翻到readme中Generated properties部分
在这里插入图片描述
根据os.name查看osname
根据os.arch获取arch
组装得到linux-x86_64
在这里插入图片描述
将linux-x86_64配置到pom文件下properties下的<os.detected.classifier>里。

  1. 编写接口文件到src/main/proto中(protoBuf3语法规范)
/**
 * 编译工具版本
 */
syntax = "proto3";
/**
 * 指定生成实体
 */
option java_multiple_files = true;
/**
 * 指定生成接口
 */
option java_generic_services = true;
/**
 * 声明包
 */
package com.grpc.grpcserver.server;
/**
 *声明实体
 */
message Person {
  string first_name = 1;
  string last_name = 2;
}

message Greeting {
  string message = 1;
}
/**
 * 声明接口
 */
service HelloWorldService {
  rpc sayHello (Person) returns (Greeting);
}
  1. 右侧打开maven插件进行编译
    在这里插入图片描述
  2. 编译结果
    在这里插入图片描述
  3. 发布
    将编译好的接口和实体进行打包发布
    打开idea自带的控制台,会自动将目录指定到模块下
    在这里插入图片描述
    切换到lib模块
    打包发布到本地maven仓库
cd grpc-lib/
mvn clean package install

查看是否打包成功
在这里插入图片描述

查看maven仓库坐标是否有该文件
在这里插入图片描述

子模块构建-server服务端

模块结构

server服务模块主要用于开放实现接口功能,开放端口给客户端使用
项目结构如图
在这里插入图片描述

创建步骤

  1. 创建一个经典的springboot模块,引入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.nces</groupId>
    <artifactId>grpc-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>grpc-server</name>
    <description>grpc-server</description>
<!--    指定父模块,同时在父模块引入该模块-->
    <parent>
        <artifactId>grpc</artifactId>
        <groupId>com.nces</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <!--        Spring-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--        lib-->
        <dependency>
            <groupId>com.nces</groupId>
            <artifactId>grpc-lib</artifactId>
        </dependency>
        <!--        grpc-->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-common</artifactId>
        </dependency>
        <dependency>
            <groupId>io.github.lognet</groupId>
            <artifactId>grpc-spring-boot-starter</artifactId>
        </dependency>
        <!--        other-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-plugin-version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.nces.grpcserver.GrpcServerApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

  1. application.properties配置服务端口
spring.application.name=grpc-server
grpc.port=9099
  1. service实现
    其中,@GRpcService声明是一个GRpc服务实现,使用它进行bean注入,就不能添加@Service一类的注解,否则会发生重复注入的情况
package com.nces.grpcserver.server;

import com.grpc.grpcserver.server.Greeting;
import com.grpc.grpcserver.server.HelloWorldServiceGrpc;
import com.grpc.grpcserver.server.Person;
import io.grpc.stub.StreamObserver;
import lombok.extern.slf4j.Slf4j;
import org.lognet.springboot.grpc.GRpcService;

/**
 * @author Xi Peng
 * @Description Grpc服务端
 * @createTime 2021年12月29日 17:04:00
 */
@GRpcService
@Slf4j
public class HelloServer extends HelloWorldServiceGrpc.HelloWorldServiceImplBase {
    @Override
    public void sayHello(Person request, StreamObserver<Greeting> responseObserver) {
        log.info("request:{}",request);
        responseObserver.onNext(Greeting.newBuilder().setMessage("当前时间为"+System.currentTimeMillis()).build());
        responseObserver.onCompleted();
    }
}
  1. 启动服务端

子模块构建-客户端

模块结构

在这里插入图片描述
客户端整合了spring-web,所以使用了传统的三层

创建步骤

  1. 创建一个空的springboot项目,引入依赖
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.nces</groupId>
    <artifactId>grpc-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>grpc-client</name>
    <description>grpc-client</description>
    <parent>
        <artifactId>grpc</artifactId>
        <groupId>com.nces</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.nces</groupId>
            <artifactId>grpc-lib</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven-plugin-version}</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <mainClass>com.nces.grpcclient.GrpcClientApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

  1. client客户端实现
package com.nces.grpcclient.client;

import com.grpc.grpcserver.server.Greeting;
import com.grpc.grpcserver.server.HelloWorldServiceGrpc;
import com.grpc.grpcserver.server.Person;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * @author Xi Peng
 * @Description
 * @createTime 2021年12月29日 19:01:00
 */
@Component
@Slf4j
public class HelloWorldClient {
    /**
     * 阻塞stub
     */
    private HelloWorldServiceGrpc.HelloWorldServiceBlockingStub serviceBl;

    @PostConstruct
    public void init(){
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 9099).usePlaintext().build();
        serviceBl = HelloWorldServiceGrpc.newBlockingStub(managedChannel);
    }

    public String sayHello(String firstName,String lastName){
        Person person = Person.newBuilder().setFirstName(firstName).setLastName(lastName).build();
        Greeting greeting = serviceBl.sayHello(person);
        return greeting.getMessage();
    }

}

  1. service层
package com.nces.grpcclient.service.impl;

import com.nces.grpcclient.client.HelloWorldClient;
import com.nces.grpcclient.service.HelloWorldService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author Xi Peng
 * @Description
 * @createTime 2021年12月29日 19:22:00
 */
@Service
public class HelloWorldServiceImpl implements HelloWorldService {
    @Resource
    private HelloWorldClient client;

    @Override
    public String helloWorld(String beginName, String endName) {
        return client.sayHello(beginName, endName);
    }
}

  1. service接口
package com.nces.grpcclient.service;

public interface HelloWorldService {
    String helloWorld(String beginName,String endName);
}
  1. controller
package com.nces.grpcclient.controller;

import com.nces.grpcclient.service.HelloWorldService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author Xi Peng
 * @Description
 * @createTime 2021年12月29日 19:24:00
 */
@RestController
@RequestMapping(path = "/hello")
public class HelloWorldController {
    @Resource
    private HelloWorldService helloWorldService;

    @GetMapping("/world")
    public String helloWorld(String beginName,String endName){
        return helloWorldService.helloWorld(beginName,endName);
    }
}

  1. 启动客户端

测试

URL:http://localhost:8080/hello/world?beginName=a&endName=b
server控制台
在这里插入图片描述
接口返回
在这里插入图片描述

grpc流

普通接口

  • 大文件传输时数据包过大,数据传输时间过长,传输完成后客户端才能使用
  • 只能一对一进行通信,无法实现轮训消息传输、

接口设计

/**
 * 编译工具版本
 */
syntax = "proto3";
/**
 * 指定生成实体
 */
option java_multiple_files = true;
/**
 * 指定生成接口
 */
option java_generic_services = true;
/**
 * 声明包
 */
package com.ncse.api.worker.service;

service TestGRpc{
  /**
  普通流
   */
  rpc test(Request) returns (Response);
  /**
  服务端流
   */
  rpc testStreamResponse(Request) returns (stream Response);
  /**
  客户端流
   */
  rpc testStreamRequest(stream Request) returns (Response);
  /**
  双向流
   */
  rpc testStream(stream Request) returns (stream Response);
}

message Request{
    string message = 1;
}
message Response{
  string message = 1;
}

客户端连接

    //阻塞式流,支持服务端流和普通流
    private TestGRpcGrpc.TestGRpcBlockingStub testBlocking;
    //非阻塞式流,只支持普通流
    private TestGRpcGrpc.TestGRpcFutureStub testFuture;
	//流,支持普通流,服务端流,客户端流和双端流
    private TestGRpcGrpc.TestGRpcStub testGRpcStub;

    @PostConstruct
    public void init() {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost", 6565).usePlaintext().build();
        testBlocking = TestGRpcGrpc.newBlockingStub(managedChannel);
        testGRpcStub = TestGRpcGrpc.newStub(managedChannel);
        testFuture = TestGRpcGrpc.newFutureStub(managedChannel);
    }

grpc普通流

服务端实现

public void test(Request request, StreamObserver<Response> responseObserver) {
        log.info("request:{}", request);
        responseObserver.onNext(Response.newBuilder().setMessage(request.toString()).build());
        responseObserver.onCompleted();
    }

客户端实现

public void print() {
        Iterator<Response> test = testBlocking.test(Request.newBuilder().setMessage("一个参数一个返回值" + new Date().toString()).build());
        while (test.hasNext()) {
            System.out.println(test.next());
        }
    }

grpc服务端流

服务端实现

@Override
    public void testStreamResponse(Request request, StreamObserver<Response> responseObserver) {
        log.info("request:{}", request);
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            responseObserver.onNext(Response.newBuilder().setMessage("服务端流" + request + ":" + i).build());
        }
        responseObserver.onCompleted();
    }

客户端实现

public void print1m() {
        Iterator<Response> test = testBlocking.testStreamResponse(Request.newBuilder().build());
        while (test.hasNext()) {
            System.out.println(test.next());
        }
    }

grpc客户端流

服务端实现

@Override
    public StreamObserver<Request> testStreamRequest(StreamObserver<Response> responseObserver) {

        StreamObserver<Request> observer = new StreamObserver<Request>() {
            @Override
            public void onNext(Request value) {
                log.info("客户端流:request:{}", value);
            }

            @Override
            public void onError(Throwable t) {
                log.error(t.getMessage());
            }

            @Override
            public void onCompleted() {
                log.info("close");
            }
        };
        observer.onNext(Request.newBuilder().setMessage("客户端流").build());
        return observer;
    }

客户端实现

public void printm1() {
        StreamObserver<Request> request = testGRpcStub.testStreamRequest(new StreamObserver<Response>() {
            @Override
            public void onNext(Response value) {
                log.info("response:{}", value);
            }

            @Override
            public void onError(Throwable t) {
                log.error(t.getMessage());
            }

            @Override
            public void onCompleted() {
                log.info("close");
            }
        });
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            request.onNext(Request.newBuilder().setMessage("客户端流:"+i).build());
        }
        request.onCompleted();
    }

grpc双端流

服务端实现

 @Override
    public StreamObserver<Request> testStream(StreamObserver<Response> responseObserver) {
        return new StreamObserver<Request>() {
            @Override
            public void onNext(Request value) {
                for (int i = 0; i < 10; i++) {
                    log.info(value.getMessage());
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    responseObserver.onNext(Response.newBuilder().setMessage("双端流服务端消息").build());
                }
            }

            @Override
            public void onError(Throwable t) {
                log.error(t.getMessage());
            }

            @Override
            public void onCompleted() {
                log.info("close");
                responseObserver.onCompleted();
            }
        };
    }
   

客户端实现

public void printmm(){
        StreamObserver<Request> stream = testGRpcStub.testStream(new StreamObserver<Response>() {
            @Override
            public void onNext(Response value) {
                log.info(value.getMessage());
            }

            @Override
            public void onError(Throwable t) {
                log.error(t.getMessage());
            }

            @Override
            public void onCompleted() {
                log.info("close");
            }
        });
        for (int i = 0; i < 10; i++) {
            stream.onNext(Request.newBuilder().setMessage("双端流客户端消息").build());
        }
        stream.onCompleted();
    }

附录

rpc框架性能对比

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐