tinyrpc/src/net/tinypb/tinypb_dispatcher.cc
2025-02-05 20:50:31 +08:00

119 lines
4.3 KiB
C++

#include "tinypb_dispatcher.hpp"
#include "logger.hpp"
#include "tinypb_closure.hpp"
#include "tinypb_controller.hpp"
#include "tinypb_data.hpp"
#include "error_code.hpp"
#include <memory>
#include <sstream>
namespace tinyrpc {
TinypbDispatcher::TinypbDispatcher() {}
TinypbDispatcher::~TinypbDispatcher() {
}
void TinypbDispatcher::dispatcher(ServerTcpConnection& conn, AbstractData& data, AbstractData& resp) {
logger() << "dispatcher";
TinypbData& request = dynamic_cast<TinypbData&>(data);
TinypbData& respond = dynamic_cast<TinypbData&>(resp);
std::string service_name;
std::string method_name;
respond.service_full_name = request.service_full_name;
respond.msg_req = request.msg_req;
logger() << "request service_full_name:" << "[" << request.service_full_name << "]";
logger() << "request msg_req:" << "[" << request.msg_req << "]";
bool ret = parseServiceFullName(request.service_full_name, service_name, method_name);
if(ret == false) {
respond.err_code = ERROR_PARSE_SERVICE_NAME;
std::stringstream ss;
ss << "not found service_name:[" << service_name << "]";
respond.err_info = ss.str();
return;
}
logger() << "request method_name:" << "[" << method_name << "]";
auto it = m_service_map.find(service_name);
if (it == m_service_map.end() || !(it->second)) {
respond.err_code = ERROR_SERVICE_NOT_FOUND;
std::stringstream ss;
ss << "not found service_name:[" << service_name << "]";
respond.err_info = ss.str();
return;
}
std::shared_ptr<Service> service = it->second;
const Method* method = service->GetDescriptor()->FindMethodByName(method_name);
// const Method* method = nullptr;
if(method == nullptr) {
respond.err_code = ERROR_METHOD_NOT_FOUND;
std::stringstream ss;
ss << "not found service_name:[" << service_name << "]";
respond.err_info = ss.str();
return;
}
std::unique_ptr<Message> requestMsg (service->GetRequestPrototype(method).New());
ret = requestMsg->ParseFromString(request.pb_data);
if(ret == false) {
respond.err_code = ERROR_FAILED_SERIALIZE;
std::stringstream ss;
ss << "faild to parse request data, request.name:[" << requestMsg->GetDescriptor()->full_name() << "]";
respond.err_info = ss.str();
return;
}
std::unique_ptr<Message> respondMsg (service->GetResponsePrototype(method).New());
auto callback = [&respond, &respondMsg] {
if(!respondMsg->SerializePartialToString(&respond.pb_data)) {
respond.pb_data = "";
logger() << respond.msg_req << "|reply error! encode reply package error";
respond.err_code = ERROR_FAILED_SERIALIZE;
respond.err_info = "failed to serilize relpy data";
} else {
logger() << respond.msg_req << "|Set server response data:" << respondMsg->ShortDebugString();
}
};
std::unique_ptr<TinypbController> rpcController(new TinypbController);
rpcController->SetMsgReq(respond.msg_req);
rpcController->SetFullName(respond.service_full_name);
rpcController->SetMethodName(method_name);
TinypbClosure done(callback);
service->CallMethod(method, rpcController.get(), requestMsg.get(), respondMsg.get(), &done /* callback */);
}
bool TinypbDispatcher::parseServiceFullName(const std::string& name, std::string& serviceName, std::string& methodName) {
if(name.empty()) return false;
auto pos = name.find(".");
if(pos == std::string::npos) return false;
serviceName = name.substr(0, pos);
methodName = name.substr(pos + 1);
// logger() << "serviceName=" << serviceName;
// logger() << "methodName=" << methodName;
return true;
}
void TinypbDispatcher::registerService(std::shared_ptr<Service>& service) {
std::string service_name = service->GetDescriptor()->full_name();
m_service_map[service_name] = service;
logger() << "success register service:" << "[" << service_name << "]";
}
}