流程一:https://blog.youkuaiyun.com/wd3cwg38/article/details/104417312
int main(int argc, char* argv[])
{
RpcServer rpc_server;
goya::rpc::echo::EchoService* echo_service = new EchoServerImpl();
if (!rpc_server.RegisterService(echo_service, false)) {
std::cout << "register service failed" << std::endl;
return -1;
}
std::string server_addr("0.0.0.0:12321");
if (!rpc_server.Start(server_addr)) {
std::cout << "start server failed" << std::endl;
return -1;
}
return 0;
}
- google实现
class EchoServer {}
- Server端实现
Coder实现一:Service
class EchoServiceImpl : public goya::rpc::echo::EchoService {
// 需要实现Echo方法
virtual void Echo(google::protobuf::RpcController* controller,
const goya::rpc::echo::EchoRequest* request,
goya::rpc::echo::EchoResponse* response,
google::protobuf::Closure* done)
{}
// ...
}
// 注意:源代码中为EchoServer,觉得不好理解改成EchoService
Coder实现二:RpcServer
class RpcServer {
public:
RpcServer();
virtual ~RpcServer();
bool Start(std::string& server_addr); // RpcServer启动
bool RegisterService(google::protobuf::Service* service, bool ownership); // RpcServer的Service注册
private:
RpcServerImpl* impl_; // RpcServer具体实现
};
Coder实现三:RpcServerImp
// Service信息记录的Struct
struct ServiceInfo {
google::protobuf::Service* service_;
const google::protobuf::ServiceDescriptor* s_descriptor_; // 不明白改字段的作用
std::map<std::string, const google::protobuf::MethodDescriptor*> m_descriptor_;
};
// RpcServerImpl类关键字段
class RpcServerImpl {
public:
bool Start(/*...*/) {}
bool RegisterService(/*...*/) {}
void ProcRpcData(/*...*/) {} // 处理RpcClient发送来的数据
// ...
private:
struct ServiceInfo {}
std::map<std::string, ServiceInfo> services_;
// ...
}
Coder实现四:Start
bool RpcServerImpl::Start(std::string& server_addr) {
server_addr_ = server_addr;
size_t split_pos = server_addr_.find(':');
std::string ip = server_addr_.substr(0, split_pos);
std::string port = server_addr_.substr(split_pos + 1);
// 使用boost.asio库
boost::asio::io_service io;
boost::asio::ip::tcp::endpoint ep(
boost::asio::ip::address::from_string(ip),
std::stoi(port)
);
boost::asio::ip::tcp::acceptor acceptor(io, ep);
while (true) {
auto socket = boost::make_shared<boost::asio::ip::tcp::socket>(io);
acceptor.accept(*socket);
std::cout << "recv from client: "
<< socket->remote_endpoint().address() << std::endl;
// meta_size
char rpc_meta_buf[sizeof(int)];
socket->receive(boost::asio::buffer(rpc_meta_buf));
int rpc_meta_size = *(int*)rpc_meta_buf;
// meta_data
std::vector<char> rpc_meta_data(rpc_meta_size, 0);
socket->receive(boost::asio::buffer(rpc_meta_data));
RpcMeta rpc_meta_data_proto;
rpc_meta_data_proto.ParseFromString(std::string(&rpc_meta_data[0], rpc_meta_data.size()));
// request_data
std::vector<char> request_data(rpc_meta_data_proto.data_size(), 0);
socket->receive(boost::asio::buffer(request_data));
std::cout << "\n************\nserver recv info: " << std::endl;
std::cout << "service_id: " << rpc_meta_data_proto.service_id() << std::endl;
std::cout << "method_id : " << rpc_meta_data_proto.method_id() << std::endl;
std::cout << "request_data_size : " << rpc_meta_data_proto.data_size() << std::endl;
std::cout << "rpc_meta_size : " << rpc_meta_size << std::endl;
std::cout << "*************\n" << std::endl;
ProcRpcData(rpc_meta_data_proto.service_id(),
rpc_meta_data_proto.method_id(), std::string(&request_data[0], request_data.size()), socket);
}
}
Coder实现五:RegisterService
// 注意此部分的实现
bool RpcServerImpl::RegisterService(google::protobuf::Service* service, bool ownership)
{
std::string method_id;
ServiceInfo service_info;
const ::google::protobuf::ServiceDescriptor* sdescriptor = service->GetDescriptor();
for (int i = 0; i < sdescriptor->method_count(); ++i) {
method_id = sdescriptor->method(i)->name();
service_info.mdescriptor_[method_id] = sdescriptor->method(i);
}
service_info.service_ = service;
services_[sdescriptor->name()] = service_info;
return true;
}
- Server端实现流程
- 实现RpcServer类,主要包括Start()和RegisterService()
- 实现Service,并在RpcServer中注册
- 启动RpcServer
- 参考文献
1、RPC流程介绍 - https://izualzhy.cn/demo-protobuf-rpc