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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| ##include <iostream> ##include <memory> ##include <string> ##include <thread>
##include "IM.Login.grpc.pb.h" ##include "IM.Login.pb.h"
##include <grpc/support/log.h> ##include <grpcpp/grpcpp.h>
using grpc::Server; using grpc::ServerAsyncResponseWriter; using grpc::ServerBuilder; using grpc::ServerCompletionQueue; using grpc::ServerContext; using grpc::Status;
using IM::Login::ImLogin; using IM::Login::IMLoginReq; using IM::Login::IMLoginRes; using IM::Login::IMRegistReq; using IM::Login::IMRegistRes;
class ServerImpl final{ public: ~ServerImpl(){ server_->Shutdown(); cq_->Shutdown(); } void Run(){ std::string server_address("0.0.0.0:50051"); 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; HandleRpcs(); } private: class CallDate{ public: CallData(ImLogin::AsyncService* service, ServerCompletionQueue* cq):service_(service),cq_(cq),status_(CREATE){ Proceed(); } virtual ~CallData(){} virtual void Proceed() {return;} ImLogin::AsyncService* service_; ServerCompletionQueue* cq_; ServerContext ctx_; enum CallStatus { CREATE, PROCESS, FINISH }; CallStatus status_; }; class RegistCallData : public CallData{ public: RegistCallData(ImLogin::AsyncService* service, ServerCompletionQueue* cq) :CallData(service, cq), responder_(&ctx_) { Proceed(); } ~RegistCallData() {} void Proceed() override { if(status_ == CREATE){ status_ = PROCESS; service_->RequestRegist(&ctx_, &request_, &responder_, cq_, cq_, this); }else if(status_ == PROCESS){ new RegistCallData(service_, cq_); reply_.set_user_name(request_.user_name()); reply_.set_user_id(10); reply_.set_result_code(0); status_ = FINISH; responder_.Finish(reply_, Status::OK, this); }else{ GPR_ASSERT(status_ == FINISH); delete this; } } private: IMRegistReq request_; IMRegistRes reply_; ServerAsyncResponseWriter<IMRegistRes> responder_; }; class LoginCallData : public CallData{ public: LoginCallData(ImLogin::AsyncService* service, ServerCompletionQueue* cq) :CallData(service, cq), responder_(&ctx_) { Proceed(); } ~LoginCallData() {} void Proceed() override { if (status_ == CREATE) { status_ = PROCESS; service_->RequestLogin(&ctx_, &request_, &responder_, cq_, cq_, this); } else if (status_ == PROCESS) { new LoginCallData(service_, cq_); reply_.set_user_id(10); reply_.set_result_code(0); status_ = FINISH; responder_.Finish(reply_, Status::OK, this); } else { GPR_ASSERT(status_ == FINISH); delete this; } } private: IMLoginReq request_; IMLoginRes reply_; ServerAsyncResponseWriter<IMLoginRes> responder_; }; void HandleRpcs() { new RegistCallData(&service_, cq_.get()); new LoginCallData(&service_, cq_.get()); void *tag; bool ok; while(true) { GPR_ASSERT(cq_->Next(&tag, &ok)); GPR_ASSERT(ok); static_cast<CallData*>(tag)->Proceed(); } } std::unique_ptr<ServerCompletionQueue> cq_; ImLogin::AsyncService service_; std::unique_ptr<Server> server_; } int main(int argc, char** argv) { ServerImpl server; server.Run();
return 0; }
|