• gRPC 四模式之 双向流RPC模式


    双向流RPC模式

    在双向流 RPC 模式中,客户端以消息流的形式发送请求到服务器端,服务器端也以消息流的形式进行响应。调用必须由客户端发起,但在此之后,通信完全基于 gRPC 客户端和服务器端的应用程序逻辑。

    为什么有了双向流模式,还要使用单向流模式?

    虽然双向流模式非常强大,但并不是所有的场景都需要这种模式。客户端流、服务端流和双向流这三种模式各有其适用的场景。

    1. 客户端流模式:在这种模式下,客户端可以连续发送多个消息到服务器,但服务器只返回一个响应。这种模式适用于客户端需要上传大量数据,但服务器只需要返回一个结果的场景,例如文件上传。

    2. 服务端流模式:在这种模式下,客户端发送一个请求到服务器,然后服务器可以连续返回多个响应。这种模式适用于服务器需要返回大量数据,但客户端只发送一个请求的场景,例如数据下载。

    3. 双向流模式:在这种模式下,客户端和服务器都可以连续发送和接收消息。这种模式适用于需要实时交互的场景,例如聊天应用。

    选择哪种模式取决于你的具体需求。如果你的应用只需要一方连续发送消息,那么客户端流或服务端流可能更适合。如果你的应用需要双方都可以连续发送和接收消息,那么双向流可能更适合。

    c++ 的双向流模式的一个实现

    在gRPC中,双向流模式的C++实现涉及到创建一个服务,该服务在.proto文件中定义,然后在服务器端和客户端实现。以下是一个简单的示例:

    首先,我们在.proto文件中定义服务:

    syntax = "proto3";
    
    service MyService {
      rpc MyMethod (stream MyRequest) returns (stream MyResponse) {}
    }
    
    message MyRequest {
      // Your request fields here
    }
    
    message MyResponse {
      // Your response fields here
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    然后,我们在服务器端实现这个服务:

    class MyServiceImpl final : public MyService::Service {
      grpc::Status MyMethod(grpc::ServerContext* context, grpc::ServerReaderWriter<MyResponse, MyRequest>* stream) override {
        MyRequest request;
        while (stream->Read(&request)) {
          // Process the request and generate a response
          MyResponse response;
          // Fill the response
          stream->Write(response);
        }
        return grpc::Status::OK;
      }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    最后,我们在客户端使用这个服务:

    class MyClient {
     public:
      explicit MyClient(std::shared_ptr<grpc::Channel> channel)
          : stub_(MyService::NewStub(channel)) {}
    
      void MyMethod() {
        grpc::ClientContext context;
        auto stream = stub_->MyMethod(&context);
        // Send requests
        for (int i = 0; i < 10; ++i) {
          MyRequest request;
          // Fill the request
          stream->Write(request);
        }
        stream->WritesDone();
        // Receive responses
        MyResponse response;
        while (stream->Read(&response)) {
          // Process the response
        }
        grpc::Status status = stream->Finish();
        if (!status.ok()) {
          // Handle the error
        }
      }
    
     private:
      std::unique_ptr<MyService::Stub> stub_;
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    代码分析
    这是一个使用gRPC编写的C++客户端程序。程序中定义了一个名为MyClient的类,该类包含一个构造函数和一个名为MyMethod的成员函数。

    构造函数接受一个std::shared_ptr类型的参数,用于连接gRPC服务器。通过该参数,MyClient类可以创建一个MyService::Stub类型的对象,该对象用于调用gRPC服务器的MyMethod方法。

    MyMethod函数用于调用gRPC服务器的MyMethod方法。首先,它创建一个grpc::ClientContext类型的对象context,然后使用stub_对象调用MyMethod方法,并将context作为参数传递。接下来,它创建一个MyRequest类型的对象request,并使用stream对象将其写入。然后,它使用循环向stream对象发送10个MyRequest类型的对象,直到完成。

    接着,它使用stream对象读取响应,并将它们存储在MyResponse类型的对象response中。然后,它使用一个无限循环来处理这些响应,直到stream对象完成。最后,它使用stream对象获取完成状态,并检查是否发生错误。如果发生错误,它将调用grpc::Status::Status方法来获取错误信息,并调用grpc::Status::Status方法来处理错误。

    总结起来,这是一个使用gRPC编写的C++客户端程序,用于调用gRPC服务器上的MyMethod方法,并将响应处理为MyResponse类型。


    分享一个有趣的 学习链接:https://xxetb.xet.tech/s/HY8za

  • 相关阅读:
    剑指 Offer 10- II. 青蛙跳台阶问题【力扣】
    Water 2.5.8 发布,一站式服务治理平台
    福建省发改委福州市营商办莅临育润大健康事业部指导视察工作
    golang gin 框架读取无法用 body 传递的表单参数
    算法通过村第十八关-回溯|青铜笔记|什么叫回溯(中篇)
    苹果电脑Mac系统运行速度又卡又慢是怎么回事?
    业务架构、应用架构、技术架构、数据架构
    speedoffice(PPT)新建幻灯片如何调整默认文本框位置
    IvorySQL3.0:基于PG16.0最新内核,实现兼容Oracle数据库再升级
    Verilog刷题[hdlbits] :Always if2
  • 原文地址:https://blog.csdn.net/qq_29111047/article/details/134485572