首页 > 编程语言 >gRPC说明及使用(java版)

gRPC说明及使用(java版)

时间:2024-11-06 10:49:26浏览次数:3  
标签:java gRPC void System 说明 build println public HelloRequest

官方文档:https://grpc.io/docs/what-is-grpc/introduction/

一 gRPC 允许你定义四种服务方法:

  • 一元 RPC,其中客户端向服务器发送单个请求并得到单个响应,就像普通函数调用一样。

    rpc SayHello(HelloRequest) returns (HelloResponse);

  • 服务器流式 RPC 中,客户端向服务器发送请求并获取流以读取一系列消息。客户端从返回的流中读取,直到没有更多消息。gRPC 保证单个RPC 调用中的消息排序。

    rpc LotsOfReplies(HelloRequest) returns (stream HelloResponse);

  • 客户端流式 RPC,客户端使用提供的流编写一系列消息并将其发送到服务器。客户端完成编写消息后,它会等待服务器读取消息并返回响应。同样,gRPC 保证了单个 RPC 调用中的消息排序。

    rpc LotsOfGreetings(stream HelloRequest) returns (HelloResponse);

  • 双向流式RPC,双方使用读写流发送一系列消息。两个流独立运行,因此客户端和服务器可以按任意顺序进行读写:例如,服务器可以等待接收所有客户端消息后再写入响应,也可以交替读取消息然后写入消息,或者采用其他读写组合。每个流中的消息顺序都会保留。

    rpc BidiHello(stream HelloRequest) returns (stream HelloResponse);

二 代码样例

1 一元 RPC

其中客户端向服务器发送单个请求并得到单个响应,就像普通函数调用一样

1.1 Greeter.proto文件

syntax = "proto3";
option java_package = "org.apache.demo.v1";
option java_multiple_files = true;
service Greeter {
  rpc SayHello(HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

1.2 client端

public class GreeterClient {

    public static void main(String[] args) {
        // 创建一个通道连接到服务端
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                .usePlaintext()  // 关闭TLS(只在开发时使用)
                .build();

        // 创建存根
        GreeterGrpc.GreeterBlockingStub stub = GreeterGrpc.newBlockingStub(channel);

        // 创建请求
        HelloRequest request = HelloRequest.newBuilder()
                .setName("World")
                .build();

        // 调用服务
        try {
            HelloReply response = stub.sayHello(request);
            System.out.println("Response: " + response.getMessage());
        } catch (StatusRuntimeException e) {
            System.err.println("RPC failed: " + e.getStatus());
        } finally {
            // 关闭通道
            channel.shutdown();
        }
    }
}

1.3 server端

public class GreeterServer {
    public static void main(String[] args) throws Exception {
        Server server = ServerBuilder.forPort(50051)
                .addService(new GreeterImpl())
                .build()
                .start();
        System.out.println("Server started on port 50051");
        server.awaitTermination();
    }

    static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
        @Override
        public void sayHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            String message = "Hello, " + request.getName();
            HelloReply reply = HelloReply.newBuilder().setMessage(message).build();
            responseObserver.onNext(reply);
            responseObserver.onCompleted();
        }
    }
}

1.4 结果

在这里插入图片描述

2 服务器流式 RPC

2.1 StreamingGreeter.proto文件

syntax = "proto3";
option java_package = "org.apache.demo.v1";
option java_multiple_files = true;
import "Greeter.proto";
service StreamingGreeter {
  rpc StreamHello(HelloRequest) returns (stream HelloReply);
}

2.2 client端

public class StreamingGreeterClient {

    public static void main(String[] args) {
        // 创建一个通道连接到服务端
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                .usePlaintext()  // 关闭TLS(只在开发时使用)
                .build();

        // 创建存根
        StreamingGreeterGrpc.StreamingGreeterBlockingStub stub = StreamingGreeterGrpc.newBlockingStub(channel);

        // 创建请求
        HelloRequest request = HelloRequest.newBuilder()
                .setName("World")
                .build();

        // 调用StreamHello服务
        try {
            // 服务器会返回多个消息
            stub.streamHello(request).forEachRemaining(response -> {
                long l = System.currentTimeMillis();
                System.out.println(l+":==:Received: " + response.getMessage());
            });
        } catch (StatusRuntimeException e) {
            System.err.println("RPC failed: " + e.getStatus());
        } finally {
            channel.shutdown();
        }
    }
}

2.3 server端

/**
 * 服务端流式
 */
public class StreamingGreeterServer {
    public static void main(String[] args) throws Exception {
        Server server = ServerBuilder.forPort(50051)
                .addService(new StreamingGreeterImpl())
                .build()
                .start();
        System.out.println("Server started on port 50051");
        server.awaitTermination();
    }

    static class StreamingGreeterImpl extends StreamingGreeterGrpc.StreamingGreeterImplBase {
        @Override
        public void streamHello(HelloRequest request, StreamObserver<HelloReply> responseObserver) {
            for (int i = 0; i < 5; i++) {
                HelloReply reply = HelloReply.newBuilder()
                        .setMessage("Hello, " + request.getName() + " #" + i)
                        .build();
                responseObserver.onNext(reply);
            }
            responseObserver.onCompleted();
        }
    }
}

2.4 结果

在这里插入图片描述

3 客户端流式 RPC

3.1 ClientStreamingGreeter.proto文件

syntax = "proto3";
option java_package = "org.apache.demo.v1";
option java_multiple_files = true;
import "Greeter.proto";
service ClientStreamingGreeter {
  rpc StreamHello(stream HelloRequest) returns (HelloReply);
}

3.2 client端

public class ClientStreamingGreeterClient {
    public static void main(String[] args) throws InterruptedException {
        // 创建一个通道连接到服务端
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50052)
                .usePlaintext()  // 关闭TLS(只在开发时使用)
                .build();
        final CountDownLatch latch = new CountDownLatch(1);
        // 创建存根  异步
        ClientStreamingGreeterGrpc.ClientStreamingGreeterStub asyncStub = ClientStreamingGreeterGrpc.newStub(channel);

        // 创建请求
        StreamObserver<HelloRequest> requestObserver = asyncStub.streamHello(new StreamObserver<HelloReply>() {
            @Override
            public void onNext(HelloReply value) {
                System.out.println("Received: " + value.getMessage());
            }

            @Override
            public void one rror(Throwable t) {
                System.err.println("RPC failed: " + t.getMessage());
            }

            @Override
            public void onCompleted() {
                System.out.println("Server completed the RPC.");
                latch.countDown();  // 完成时释放Latch
            }
        });

        // 客户端发送多个请求
        try {
            requestObserver.onNext(HelloRequest.newBuilder().setName("John").build());
            requestObserver.onNext(HelloRequest.newBuilder().setName("Jane").build());
            requestObserver.onNext(HelloRequest.newBuilder().setName("Doe").build());

            // 结束请求
            requestObserver.onCompleted();
        } catch (Exception e) {
            System.err.println("Error sending requests: " + e.getMessage());
            requestObserver.onError(e);
        } finally {
            latch.await();
            channel.shutdown();
        }
    }
}

3.2 server端

public class ClientStreamingGreeterServer {

    public static void main(String[] args) throws Exception {
        Server server = ServerBuilder.forPort(50052)
                .addService(new ClientStreamingGreeterImpl())
                .build()
                .start();
        System.out.println("Server started on port 50051");
        server.awaitTermination();
    }

    static class ClientStreamingGreeterImpl extends ClientStreamingGreeterGrpc.ClientStreamingGreeterImplBase {
        @Override
        public StreamObserver<HelloRequest> streamHello(StreamObserver<HelloReply> responseObserver) {
            return new StreamObserver<HelloRequest>() {
                int count = 0;

                @Override
                public void onNext(HelloRequest value) {
                    System.out.println(value.getName());
                    count++;
                }

                @Override
                public void one rror(Throwable t) {
                }

                @Override
                public void onCompleted() {
                    HelloReply reply = HelloReply.newBuilder()
                            .setMessage("Received " + count + " messages")
                            .build();
                    responseObserver.onNext(reply);
                    responseObserver.onCompleted();
                    System.out.println(reply.getMessage());
                }
            };
        }
    }
}

3.4 结果

在这里插入图片描述

4 双向流式RPC

4.1 BidirectionalStreamingGreeter.proto文件

syntax = "proto3";
option java_package = "org.apache.demo.v1";
option java_multiple_files = true;
import "Greeter.proto";
service BidirectionalStreamingGreeter {
  rpc StreamHello(stream HelloRequest) returns (stream HelloReply);
}

4.1 client端

public class BidirectionalStreamingGreeterClient {
    public static void main(String[] args) throws InterruptedException {
        // 创建一个通道连接到服务端
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 50051)
                .usePlaintext()  // 关闭TLS(只在开发时使用)
                .build();
        final CountDownLatch latch = new CountDownLatch(1);
        // 创建存根 异步
        BidirectionalStreamingGreeterGrpc.BidirectionalStreamingGreeterStub stub = BidirectionalStreamingGreeterGrpc.newStub(channel);

        // 创建请求
        StreamObserver<HelloRequest> requestObserver = stub.streamHello(new StreamObserver<HelloReply>() {
            @Override
            public void onNext(HelloReply helloReply) {
                System.out.println("Received from server: " + helloReply.getMessage());
            }

            @Override
            public void one rror(Throwable throwable) {

            }

            @Override
            public void onCompleted() {
                latch.countDown();
                System.out.println("Server completed the RPC.");
            }
        });
        // 客户端发送多个请求
        try {
            requestObserver.onNext(HelloRequest.newBuilder().setName("Alice").build());
            requestObserver.onNext(HelloRequest.newBuilder().setName("Bob").build());
            requestObserver.onNext(HelloRequest.newBuilder().setName("Charlie").build());

            // 结束请求
            requestObserver.onCompleted();
        } catch (Exception e) {
            System.err.println("Error sending requests: " + e.getMessage());
            requestObserver.onError(e);
        } finally {
            latch.await();
            channel.shutdown();
        }
    }


}

4.1 server端

public class BidirectionalStreamingGreeterServer {

    public static void main(String[] args) throws InterruptedException, IOException {
        Server server = ServerBuilder.forPort(50051)
                .addService(new BidirectionalStreamingGreeterImpl())
                .build()
                .start();
        System.out.println("Server started on port 50051");
        server.awaitTermination();
    }

    static class BidirectionalStreamingGreeterImpl extends BidirectionalStreamingGreeterGrpc.BidirectionalStreamingGreeterImplBase{
        @Override
        public StreamObserver<HelloRequest> streamHello(StreamObserver<HelloReply> responseObserver) {
            return new StreamObserver<HelloRequest>() {
                @Override
                public void onNext(HelloRequest helloRequest) {
                    HelloReply reply = HelloReply.newBuilder()
                            .setMessage("Hello, " + helloRequest.getName())
                            .build();
                    responseObserver.onNext(reply);
                }

                @Override
                public void one rror(Throwable throwable) {

                }

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

4.4 结果

在这里插入图片描述

标签:java,gRPC,void,System,说明,build,println,public,HelloRequest
From: https://blog.csdn.net/weixin_46316820/article/details/143502900

相关文章

  • Java中的I/O模型——BIO、NIO、AIO
    1. BIO(BlockingI/O)1. 1BIO(BlockingI/O)模型概述        BIO,即“阻塞I/O”(BlockingI/O),是一种同步阻塞的I/O模式。它的主要特点是,当程序发起I/O请求(比如读取数据或写入数据)时,程序会一直等到这个请求完成,才继续往下执行。在BIO模型下,每个连接都需要一个独立的线程......
  • java设计模式之工厂模式
    简单分享下java中设计模式–工厂模式工厂模式(FactoryPattern)是面向对象编程中常用的设计模式之一,它属于创建型模式。工厂模式的主要目的是使用工厂方法来创建对象,而不是直接使用new关键字实例化对象。这样可以提高程序的扩展性和维护性。以下是Java中简单工厂模式的案......
  • JavaScript用法
    JavaScript 用法HTML中的Javascript脚本代码必须位于 <script> 与 </script> 标签之间。Javascript脚本代码可被放置在HTML页面的 <body> 和 <head> 部分中。<script>标签如需在HTML页面中插入JavaScript,请使用<script>标签。<script>和</script>......
  • 宁德时代Java面试题及参考答案
    MySQL的底层实现机制是怎样的?MySQL主要包括以下几个核心的底层实现部分。存储引擎层是MySQL的关键。InnoDB是最常用的存储引擎,它以页为单位进行存储,默认页大小是16KB。数据存储在表空间中,表空间可以由多个文件组成。InnoDB采用了B+树的数据结构来存储索引和数据......
  • 【java】实战-力扣题库:有序数组的平方
    问题描述给你一个按 非递减顺序 排序的整数数组 nums,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。问题分析:既然给定的是一个非递减顺序的数组我们可以使用双指针,一个指向左边,一个指向右边,比较两边平方后的大小。哪个大,就把那个数放到当前数......
  • 讲解Java字符串
    字符串1.字符串的创建(1)字面量创建(2)使用`new`关键字2.字符串的不可变性3.字符串池(StringPool)4.String类的常用方法(1)`length()`(2)`charAt(intindex)`(3)`substring(intstart)`和`substring(intstart,intend)`(4)`toUpperCase()`和`toLowerC......
  • Nginx 常用参数详解和举例说明实操指南
    Nginx常用参数详解和举例说明实操指南一、引言1.参数详解的目的和意义Nginx的配置参数是优化性能和提升安全性的关键。通过合理配置这些参数,可以显著提高Nginx的性能,减少资源消耗,增强系统的稳定性和安全性。2.适用人群和场景运维工程师:负责Nginx的日常管理和维护,需......
  • 初学Java基础---Day21---正则表达式,日期类,Math类,Random类,System类,Runtime类,大数值运
    一,正则表达式理解:        符合某个语句规范的字符串案例://案例:把一个字符串中带电话号码替换成130****1111的形式Stringstr="小红13012341111小绿15112342222小黑13912343333";//分析:电话号码可以分为三组如:(130)(1234)(1111)其中第一组中的1是固定/......
  • java计算机毕业设计基于nginx负载均衡的慢性病专家系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景随着互联网技术的飞速发展,医疗行业也在不断寻求数字化转型。在当今社会,慢性病患者数量逐渐增多,对医疗资源的分配和管理提出了更高的要求。传统的......
  • java计算机毕业设计云南美食管理系统(开题+程序+论文)
    本系统(程序+源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、研究背景在当今数字化迅猛发展的时代,美食行业的管理与运营模式正面临着巨大的变革需求。云南,作为我国美食文化的璀璨明珠,其美食文化源远流长,拥有着令人惊......