ProtoBuff之GRPC(流式)

有了前面的基础 我们已经构建了服务端和客户端连接的工具类  也已经熟悉了通过maven去处理对应的proto文件  

如果有不是很清楚的可以看看前面的基础内容  或者有不足之处欢迎指正!

--------------------------------------------------------------------------------------------------------------------------------------------

今天我们来熟悉一下4种GRPC的通信方式 我们还是先配置下maven的pom.xml

<?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>modle</groupId>
    <artifactId>modle</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>

    <modules>
        <module>ServerGrpc</module>
        <module>ClientGrpc</module>
        <module>Demo</module>
    </modules>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <grpc.version>1.20.0</grpc.version>
        <os.plugin.version>1.5.0.Final</os.plugin.version>
        <protobuf.plugin.version>0.5.1</protobuf.plugin.version>
        <protoc.version>3.5.1</protoc.version>
    </properties>
 <dependencies>
        <dependency>
            <groupId>model.grpc.util</groupId>
            <artifactId>GrpcUtil</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-netty-shaded</artifactId>
            <version>1.20.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
            <version>1.20.0</version>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
            <version>1.20.0</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.29.Final</version>
        </dependency>
  <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.yaml</groupId>
            <artifactId>snakeyaml</artifactId>
            <version>1.24</version>
        </dependency>
  <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-protobuf</artifactId>
        </dependency>
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-stub</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>3.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java-util</artifactId>
            <version>3.7.1</version>
        </dependency>
    </dependencies>
 <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.grpc</groupId>
                <artifactId>grpc-bom</artifactId>
                <version>${grpc.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <build>
        <extensions>
            <extension>
                <groupId>kr.motd.maven</groupId>
                <artifactId>os-maven-plugin</artifactId>
                <version>${os.plugin.version}</version>
            </extension>
        </extensions>
 <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <compilerArgs>
                        <arg>-parameters</arg>
                    </compilerArgs>
                </configuration>
            </plugin>
            <plugin>
  <groupId>org.xolstice.maven.plugins</groupId>
                <artifactId>protobuf-maven-plugin</artifactId>
                <version>${protobuf.plugin.version}</version>
                <configuration>
                    <protocArtifact>com.google.protobuf:protoc:${protoc.version}:exe:${os.detected.classifier}
                    </protocArtifact>
                    <pluginId>grpc-java</pluginId>
                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}
                    </pluginArtifact>
                    <attachProtoSources>false</attachProtoSources>
                    <clearOutputDirectory>false</clearOutputDirectory>
                    <outputDirectory>${basedir}/src/main/java</outputDirectory>
                </configuration>
<executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>compile-custom</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

其次我们开始编写对应的proto文件

syntax = "proto3";

package Demo05GRPC.proto;

option java_package = "Demo05GRPC.proto";

option java_outer_classname = "StudentProto";

option java_multiple_files = true;


service StudentRpcService {

    //单向阻塞数据传递
    rpc getRealName (StudentRequest) returns (StudentResponse) {
    };

    //单向服务器端流式响应
    rpc getRealByAge (ByAgeRequest) returns (stream StudentByAgeResponse) {
    };

    //单向客户端端流式请求
    rpc getStudentByAge (stream ByAgeRequest) returns (StudentListResponse) {
    };

    //双向流式请求和响应
    rpc getStudentByBItalk (stream StreamRequest) returns (stream StreamResponse) {
    };
}

message StudentRequest {
    string name = 1;
}

message StudentResponse {
    string realName = 1;
}

message ByAgeRequest {
    string age = 1;
}

message StudentByAgeResponse {
    string name = 1;
    string age = 2;
}

message StudentListResponse {
    repeated StudentByAgeResponse response = 1;
}


message StreamRequest {
    string request_info = 1;
}


message StreamResponse {
    string response_info = 1;
}

通过maven编译和生成对应的java类  如下所示

然后我们编写对应的GRPC生成的远程服务的实现类

ServerStudentImp(注意这个类启动服务器时候需要加载)

package Demo05GRPC;

import Demo05GRPC.proto.*;
import io.grpc.stub.StreamObserver;

import java.util.UUID;


public class ServerStudentImp extends StudentRpcServiceGrpc.StudentRpcServiceImplBase {



    //单向阻塞数据传递
    @Override
    public void getRealName(StudentRequest request, StreamObserver<StudentResponse> responseObserver) {
        responseObserver.onNext(StudentResponse.newBuilder().setRealName("张三").build());
        responseObserver.onNext(StudentResponse.newBuilder().setRealName("李四").build());
        responseObserver.onCompleted();
    }

    //单向服务器端流式响应
    @Override
    public void getRealByAge(ByAgeRequest request, StreamObserver<StudentByAgeResponse> responseObserver) {
        responseObserver.onNext(StudentByAgeResponse.newBuilder().setName("李四").build());
        responseObserver.onNext(StudentByAgeResponse.newBuilder().setAge("22").build());

        responseObserver.onNext(StudentByAgeResponse.newBuilder().setName("战三").build());
        responseObserver.onNext(StudentByAgeResponse.newBuilder().setAge("25").build());
        responseObserver.onCompleted();
    }

    //单向客户端端流式请求
    @Override
    public StreamObserver<ByAgeRequest> getStudentByAge(StreamObserver<StudentListResponse> responseObserver) {

        return new StreamObserver<ByAgeRequest>() {
            //请求是流式  请求一次  返回一次
            @Override
            public void onNext(ByAgeRequest byAgeRequest) {
                byAgeRequest.getAge();
            }

            @Override
            public void onError(Throwable throwable) {

            }
            @Override
            public void onCompleted() {
                StudentByAgeResponse                 response=StudentByAgeResponse.newBuilder().setAge("22").setName("张三").build();
                StudentByAgeResponse response1=StudentByAgeResponse.newBuilder().setAge("23").setName("王五").build();
                StudentByAgeResponse respons2=StudentByAgeResponse.newBuilder().setAge("24").setName("赵6").build();
                StudentListResponse listResponse=StudentListResponse.newBuilder().addResponse(response).addResponse(response1).addResponse(respons2).build();
                responseObserver.onNext(listResponse);
                responseObserver.onCompleted();
            }
        };
    }

  //双向流式请求和响应
    @Override
    public StreamObserver<StreamRequest> getStudentByBItalk(StreamObserver<StreamResponse> responseObserver) {

        return new StreamObserver<StreamRequest>() {
            @Override
            public void onNext(StreamRequest streamRequest) {
                responseObserver.onNext(StreamResponse.newBuilder().setResponseInfo(UUID.randomUUID()+"").build());
            }

            @Override
            public void onError(Throwable throwable) {
                System.out.println(throwable.getMessage());
            }

            @Override
            public void onCompleted() {
                responseObserver.onCompleted();
            }
        };
    }
}

最后就是我们的客户端和服务端的测试代码了

服务端如下:

package Demo05GRPC;
import io.grpc.Server;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;

import java.io.IOException;

public class ServerGrpc {

    private Server server;

    public void start() throws IOException {
        NettyServerBuilder serverBuilder=NettyServerBuilder.forPort(8002);
        serverBuilder.addService(new ServerStudentImp());//将所有的远程服务类加进去管理
        //我这里只有一个实现类

        this.server = serverBuilder.build();
        this.server.start();
    }



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

 /**
     * 阻塞等待RPC服务器停止
     */
    public void blockUntilShutdown() {
        if (server != null) {
            try {
                server.awaitTermination();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    public static void main(String[] args) throws IOException {
        ServerGrpc serverGrpc=new ServerGrpc();
        serverGrpc.start();
        serverGrpc.blockUntilShutdown();
    }



}

客户端代码:

package Demo05GRPC;

import Demo05GRPC.proto.*;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.stub.StreamObserver;

public class GrpcClient {


    public static void main(String[] args) {
        ManagedChannel managedChannel = ManagedChannelBuilder.forAddress("localhost"
                , 8002).usePlaintext(true).build();
        /*StudentRpcServiceGrpc.StudentRpcServiceBlockingStub stub = StudentRpcServiceGrpc.newBlockingStub(managedChannel);
        java.util.Iterator<Demo05GRPC.proto.StudentByAgeResponse> response = stub.getRealByAge(ByAgeRequest.newBuilder().setAge("222").build());

        while (response.hasNext()){
            StudentByAgeResponse response1= response.next();
            System.out.println(response1.getAge());
            System.out.println(response1.getName());
        }*/
  /*StreamObserver<StudentListResponse> streamObserver=  new StreamObserver<StudentListResponse>() {
            @Override
            public void onNext(StudentListResponse value) {
                value.getResponseList().forEach(e->{
                    System.out.println(e.getName());
                    System.out.println(e.getAge());
                });
            }
            @Override
            public void onError(Throwable throwable) {

            }
            @Override
            public void onCompleted() {

            }
        };
 StudentRpcServiceGrpc.StudentRpcServiceStub stub1=StudentRpcServiceGrpc.newStub(managedChannel);
        StreamObserver<Demo05GRPC.proto.ByAgeRequest> response1= stub1.getStudentByAge(streamObserver);
        response1.onNext(ByAgeRequest.newBuilder().setAge("22").build());
        response1.onNext(ByAgeRequest.newBuilder().setAge("23").build());
        response1.onNext(ByAgeRequest.newBuilder().setAge("24").build());
        response1.onNext(ByAgeRequest.newBuilder().setAge("25").build());
        response1.onNext(ByAgeRequest.newBuilder().setAge("26").build());
        response1.onCompleted();

        try {
            Thread.sleep(5000);
        }catch (Exception e){
            e.getMessage();
        }

        }*/
  StudentRpcServiceGrpc.StudentRpcServiceStub stub1 = StudentRpcServiceGrpc.newStub(managedChannel);

        StreamObserver<Demo05GRPC.proto.StreamRequest> requestStreamObserver = stub1.getStudentByBItalk(new StreamObserver<StreamResponse>() {
            @Override
            public void onNext(StreamResponse streamResponse) {
                System.out.println(streamResponse.getResponseInfo());
            }

            @Override
            public void onError(Throwable throwable) {

            }

            @Override
            public void onCompleted() {

            }
        });
 for (int i = 0; i < 10; i++) {
            requestStreamObserver.onNext(StreamRequest.newBuilder().setRequestInfo(System.currentTimeMillis() + "").build());
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.getMessage();
            }
        }

        try {
            Thread.sleep(5000);
        } catch (Exception e) {
            e.getMessage();
        }
    }
}

看到这里 我们可以对照之前写的工具类 已经封装好了  结合项目只需要将我们远程服务的所有实现在初始化的时候调用NettyServerBuilder.addService()就可以使用我们的grpc 服务与服务之间的轻松访问。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值