• grpc c++流式传输demo


    目录结构

     编译脚本build.sh

    if [ -d "./proto_code" ];then
        rm -rf ./proto_code
    fi
    mkdir ./proto_code
    protoc -I ./ --grpc_out=./proto_code --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` ./reduce.proto
    protoc -I ./ --cpp_out=./proto_code ./reduce.proto
    
    if [ -d "./build" ];then
        rm -rf ./build
    fi
    mkdir ./build
    cd build
    cmake ..
    make
    cd ..

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.5)
    project(test2)
    find_package(Threads REQUIRED)
    find_package(Protobuf REQUIRED)
    set(_PROTOBUF_LIBPROTOBUF protobuf::libprotobuf)
    set(_REFLECTION gRPC::grpc++_reflection)
    find_package(gRPC CONFIG REQUIRED)
    set(_GRPC_GRPCPP gRPC::grpc++)
    
    SET(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} "-pthread")
    
    
    include_directories("${CMAKE_CURRENT_BINARY_DIR}/../proto_code")
    set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/../proto_code/reduce.pb.cc")
    set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/../proto_code/reduce.pb.h")
    set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/../proto_code/reduce.grpc.pb.cc")
    set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/../proto_code/reduce.grpc.pb.h")
    # hw_grpc_proto
    add_library(hw_grpc_proto
      ${hw_grpc_srcs}
      ${hw_grpc_hdrs}
      ${hw_proto_srcs}
      ${hw_proto_hdrs})
    target_link_libraries(hw_grpc_proto
      ${_REFLECTION}
      ${_GRPC_GRPCPP}
      ${_PROTOBUF_LIBPROTOBUF})
    
    # Targets greeter_[async_](client|server)
    foreach(_target
      reduce_server reduce_client)
      add_executable(${_target} "${_target}.cc")
      target_link_libraries(${_target}
        hw_grpc_proto
        ${_REFLECTION}
        ${_GRPC_GRPCPP}
        ${_PROTOBUF_LIBPROTOBUF})
    endforeach()

    proto文件

    syntax="proto3";
    
    option java_multiple_files=true;
    option java_package="io.grpc.example.reduce";
    option java_outer_classname="ReduceProto";
    option objc_class_prefix="RDC";
    
    package reduce;
    
    service ReduceService{
        rpc getData(stream Data) returns(stream Data){}
    }
    
    message Data{
        int32 data=1;
    }

    服务端代码

    #include <iostream>
    #include <string>
    #include <memory>
    #include <pthread.h>
    #include <unistd.h>
    #include <vector>
    
    #include <grpc/grpc.h>
    #include <grpcpp/security/server_credentials.h>
    #include <grpcpp/server.h>
    #include <grpcpp/server_builder.h>
    #include <grpcpp/server_context.h>
    #include "./proto_code/reduce.grpc.pb.h"
    
    using std::cout;
    using std::endl;
    using std::string;
    using std::unique_ptr;
    using std::shared_ptr;
    using std::vector;
    
    using grpc::Server;
    using grpc::ServerBuilder;
    using grpc::ServerContext;
    using grpc::ServerReader;
    using grpc::ServerWriter;
    using grpc::ServerReaderWriter;
    using grpc::Status;
    
    using reduce::Data;
    using reduce::ReduceService;
    
    class ReduceImpl final: public ReduceService::Service{
    public:
        Status getData(ServerContext* context,ServerReaderWriter<Data,Data>* stream)override
        {
            Data read_data;
            while(stream->Read(&read_data))
            {
                pthread_mutex_lock(&mu_);
                received_data.push_back(read_data);
                cout<<"receive data: "<<read_data.data()<<endl;
                pthread_mutex_unlock(&mu_);
            }
            for(const Data& n:received_data)
            {
                stream->Write(n);
                cout<<"=====write "<<n.data()<<endl;
            }
            return Status::OK;
        }
    private:
        pthread_mutex_t mu_=PTHREAD_MUTEX_INITIALIZER;
        vector<Data> received_data;
    };
    
    void RunServer()
    {
        string server_addr("0.0.0.0:50051");
        ReduceImpl service;
        ServerBuilder builder;
        builder.AddListeningPort(server_addr,grpc::InsecureServerCredentials());
        builder.RegisterService(&service);
        unique_ptr<Server> server(builder.BuildAndStart());
        cout<<"Server listening on "<<server_addr<<endl;
        server->Wait();
    }
    
    int main(int argc,char** argv)
    {
        RunServer();
        return 0;
    }

    客户端代码

    #include <iostream>
    #include <memory>
    #include <string>
    #include <pthread.h>
    #include <unistd.h>
    #include <thread>
    #include <vector>
    
    #include <grpc/grpc.h>
    #include <grpcpp/channel.h>
    #include <grpcpp/client_context.h>
    #include <grpcpp/create_channel.h>
    #include <grpcpp/security/credentials.h>
    #include "./proto_code/reduce.grpc.pb.h"
    
    using std::cout;
    using std::endl;
    using std::string;
    
    using grpc::Channel;
    using grpc::ClientContext;
    using grpc::ClientReader;
    using grpc::ClientWriter;
    using grpc::ClientReaderWriter;
    using grpc::Status;
    
    using reduce::Data;
    using reduce::ReduceService;
    
    class ReduceClient{
    public:
        ReduceClient(std::shared_ptr<Channel> channel):stub_(ReduceService::NewStub(channel)){}
        void sendData()
        {
            ClientContext context;
            std::shared_ptr<ClientReaderWriter<Data,Data>> stream(stub_->getData(&context));
    
            auto thread_func=[stream](){
                std::vector<Data> v_tmp;
                for(int i=0;i<50;++i)
                {
                    Data tmp;
                    tmp.set_data(i);
                    v_tmp.push_back(tmp);
                }
                for(Data& d:v_tmp)
                {
                    std::cout<<"write"<<std::endl;
                    stream->Write(d);
                }
                stream->WritesDone();
            };
            //pthread_create(&client_send_thread,NULL,(void* (*)(void*))&thread_func,NULL);
            std::thread writer(thread_func);
            
            Data recv_data;
            while(stream->Read(&recv_data))
            {
                std::cout<<"data "<<recv_data.data()<<" send success"<<std::endl;
            }
            writer.join();
    
            Status status=stream->Finish();
            if(!status.ok())
            {
                std::cout<<"getData rpc failed"<<std::endl;
            }
        }
    private:
        std::unique_ptr<ReduceService::Stub> stub_;
        pthread_t client_send_thread;
    };
    
    int main(int argc,char** argv)
    {
        ReduceClient client1(grpc::CreateChannel("localhost:50051",grpc::InsecureChannelCredentials()));
        client1.sendData();
        return 0;
    }

    流式传输使用stream,stream中有Read和Write,客户端和服务端都要调用Read和Write

    目前的问题是没办法写成死循环,就是一直发送数据。一旦写成死循环就会报这个错

    E0323 16:50:21.462651883 1254646 call_op_set.h:985] assertion failed: false
    Aborted (core dumped)

    然后core就dump了

  • 相关阅读:
    Codeforces ECR 83 C. Adding Powers (位运算)
    Codeforces Round #636div3 D. Constant Palindrome Sum (划分区间,差分)
    Codeforces Round #603 C. Everyone is a Winner!
    Centos7 下搭建SVN + Apache 服务器 风行天下
    完整部署CentOS7.2+OpenStack+kvm 云平台环境(1)基础环境搭建 风行天下
    云计算的理解 风行天下
    Python之路3【知识点】白话Python编码和文件操作 风行天下
    C#中TreeView组件使用方法初步
    复制文件时explorer.exe出错解决方法
    C# 里TreeView绑定数据库实现分类
  • 原文地址:https://www.cnblogs.com/wangtianning1223/p/16045640.html
Copyright © 2020-2023  润新知