grpc异步服务器 C++

1.首先编写proto文件;

GrpcTest.proto内容如下:

syntax = "proto3";

package GrpcTestCalc;

service Caltulator {
    rpc AddResult(Request) returns (Response) {}
    rpc SubResult(Request) returns (Response) {}
}

message Request {
    int32 numA = 1;
    int32 numB = 2;
}

message Response {
    int32 result = 1;
}

 对该文件单独进行编译,产生grpc相关的四个文件;

2.编写grpc服务端代码;

GrpcTestMain.cpp内容如下:

/*
tfk 2018.09.06
*/

#include
#include
#include
#include
#include

#include
#include

#include "GrpcTest.grpc.pb.h"

using grpc::Server;
using grpc::ServerAsyncResponseWriter;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerCompletionQueue;
using grpc::Status;
using GrpcTestCalc::Request;
using GrpcTestCalc::Response;
using GrpcTestCalc::Caltulator;


class ServerImpl final {
public:
    ~ServerImpl() {
        server_->Shutdown();
        cq_->Shutdown();
    }

    void Run() {
        std::string server_address("x.x.x.x:port");
        ServerBuilder builder;
        builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
        builder.RegisterService(&service_);
        cq_ = builder.AddCompletionQueue();
        server_ = builder.BuildAndStart();
        std::cout << "Server listening on " << server_address << std::endl;

        /*for (int i = 0; i < 8; i++)
        {
            _beginthreadex(NULL,
                0,
                ServerImpl::ThreadHandlerRPC,
                (void*)this,
                0,
                0);
        }*/

        HandleRPCS();

    }

private:
    class CallData {
    public:
        enum ServiceType {
            SS_AddStudent = 0,
            SS_SubTeacher
        };

    public:
        CallData(Caltulator::AsyncService* service, ServerCompletionQueue* cq, ServiceType s_type)
            :service_(service), cq_(cq), s_type_(s_type), add_responder_(&ctx_), sub_responder_(&ctx_), status_(CREATE) {
            Process();
        }

        void Process() {
            if (status_ == CREATE)
            {
                status_ = PROCESS;
                switch (s_type_)
                {
                case ServerImpl::CallData::SS_AddStudent:
                    service_->RequestAddResult(&ctx_, &add_request, &add_responder_, cq_, cq_, this);
                    break;
                case ServerImpl::CallData::SS_SubTeacher:
                    service_->RequestSubResult(&ctx_, &sub_request, &sub_responder_, cq_, cq_, this);
                    break;
                default:
                    break;
                }
            }
            else if (status_ == PROCESS) {
                status_ = FINISH;
                new CallData(service_, cq_, this->s_type_);
                switch (s_type_)
                {
                case ServerImpl::CallData::SS_AddStudent:
                {
                    add_reply_.set_result(add_request.numa() + add_request.numb());

                    status_ = FINISH;

                    add_responder_.Finish(add_reply_, Status::OK, this);
                }
                break;
                case ServerImpl::CallData::SS_SubTeacher:
                {
                    sub_reply_.set_result(sub_request.numa() - sub_request.numb());

                    status_ = FINISH;

                    sub_responder_.Finish(sub_reply_, Status::OK, this);
                }
                break;
                default:
                    break;
                }
            }
            else {
                GPR_ASSERT(status_ == FINISH);
                delete this;
            }

        }

    private:
        Caltulator::AsyncService* service_;
        ServerCompletionQueue* cq_;
        ServerContext ctx_;
        ServiceType s_type_;

        Request add_request;
        Response add_reply_;
        ServerAsyncResponseWriter add_responder_;

        Request sub_request;
        Response sub_reply_;
        ServerAsyncResponseWriter sub_responder_;

        enum CallStatus {
            CREATE,
            PROCESS,
            FINISH
        };
        CallStatus status_;
    };

private:

    /*static unsigned __stdcall ThreadHandlerRPC(void* lparam) {
        ServerImpl* impl = (ServerImpl*)lparam;
        impl->HandleRPCS();
        return 1;
    }*/

    void HandleRPCS() {
        new CallData(&service_, cq_.get(), ServerImpl::CallData::SS_AddStudent);
        new CallData(&service_, cq_.get(), ServerImpl::CallData::SS_SubTeacher);
        void* tag;
        bool ok;
        while (true) {
            GPR_ASSERT(cq_->Next(&tag, &ok));
            GPR_ASSERT(ok);
            static_cast(tag)->Process();
        }
    }


private:
    std::shared_ptr cq_;
    Caltulator::AsyncService service_;
    std::shared_ptr server_;


};


int main()
{
    ServerImpl server;
    server.Run();

    return 0;
}

 上述代码为服务端代码,客户端代码较简单,不做累述。

你可能感兴趣的:(grpc,c++)