RPC流程二 - Server端编写

本文详细介绍了RPC服务端的实现过程,包括google的实现方案以及Server端的步骤。具体涵盖从Service到RpcServer的编码实现,如Service、RpcServerImp、Start和RegisterService的功能。同时,阐述了RpcServer类的核心方法Start()和RegisterService(),以及如何在RpcServer中注册Service并启动服务。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

流程一: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端实现流程

  1. 实现RpcServer类,主要包括Start()RegisterService()
  2. 实现Service,并在RpcServer中注册
  3. 启动RpcServer

- 参考文献

1、RPC流程介绍 - https://izualzhy.cn/demo-protobuf-rpc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值