rpc 部分逻辑 未完成

This commit is contained in:
yhy 2025-01-22 17:58:45 +08:00
parent df8789f6c6
commit 9d9fb69cbb
13 changed files with 2480 additions and 16 deletions

View File

@ -2,11 +2,13 @@ cmake_minimum_required(VERSION 3.0)
project(tinyrpc)
# set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
enable_language(CXX ASM)
add_compile_options(-g -Wall -std=c++17)
add_compile_options(-g -Wall)
include_directories(includes/coroutine)
include_directories(includes/log)
@ -14,6 +16,7 @@ include_directories(includes/net)
include_directories(includes/net/tcp)
include_directories(includes/net/tinypb)
aux_source_directory(${CMAKE_SOURCE_DIR}/src SRC_LIST)
aux_source_directory(${CMAKE_SOURCE_DIR}/src/coroutine COROUTINE_SRC_LIST)
aux_source_directory(${CMAKE_SOURCE_DIR}/src/net NET_SRC_LIST)
aux_source_directory(${CMAKE_SOURCE_DIR}/src/net/tcp TCP_SRC_LIST)
@ -29,6 +32,7 @@ set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
add_library(tinyrpc
# ${SRC_LIST}
${COROUTINE_SRC_LIST}
${TCP_SRC_LIST}
${NET_SRC_LIST}
@ -43,6 +47,53 @@ add_executable(test_tinyrpc
${TEST_SRC_LIST}
)
# abseil-cpp
add_subdirectory(./third_party/abseil-cpp absl)
set(ABSEL_LIBARARY
absl::absl_check
absl::absl_log
absl::algorithm
absl::base
absl::bind_front
absl::bits
absl::btree
absl::cleanup
absl::cord
absl::core_headers
absl::debugging
absl::die_if_null
absl::dynamic_annotations
absl::flags
absl::flat_hash_map
absl::flat_hash_set
absl::function_ref
absl::hash
absl::layout
absl::log_initialize
absl::log_severity
absl::memory
absl::node_hash_map
absl::node_hash_set
absl::optional
absl::span
absl::status
absl::statusor
absl::strings
absl::synchronization
absl::time
absl::type_traits
absl::utility
absl::variant
)
#
target_link_libraries(tinyrpc PRIVATE protobuf) # Protobuf
target_link_libraries(tinyrpc PRIVATE ${ABSEL_LIBARARY}) # Protobuf
target_link_libraries(test_tinyrpc PRIVATE tinyrpc)
target_link_libraries(test_tinyrpc PUBLIC protobuf)
target_link_libraries(test_tinyrpc PUBLIC stdc++)

View File

@ -10,6 +10,8 @@ namespace tinyrpc {
class TinypbDispatcher : public AbstractDispatcher {
using Service = google::protobuf::Service;
using Method = google::protobuf::MethodDescriptor;
using Message = google::protobuf::Message;
public:
TinypbDispatcher();
~TinypbDispatcher();

View File

@ -275,3 +275,5 @@ namespace tinyrpc {
t_reactor = nullptr;
}
}

View File

@ -138,6 +138,8 @@ namespace tinyrpc {
std::unique_ptr<AbstractData> resp(new TinypbData);
m_server.getDispatcher().dispatcher(*this, *data, *resp);
m_server.getCoder().encoder(m_writeBuffer, *resp);
}
}

View File

@ -13,7 +13,7 @@ namespace tinyrpc {
static const char PB_START = 0x02; // start char
static const char PB_END = 0x03; // end char
static const int MSG_REQ_LEN = 20; // default length of msg_req
// static const int MSG_REQ_LEN = 20; // default length of msg_req
TinypbCoder::TinypbCoder() {
// TODO
@ -79,7 +79,7 @@ namespace tinyrpc {
buf[cur_index++] = PB_END;
memcpy(buffer.getWriteAddress(), buf.get(), pk_len);
buffer.writeOffset(pk_len);
return true;
}
@ -93,17 +93,17 @@ namespace tinyrpc {
bool isFullPack = false;
int pack_len = -1;
for(int i = 0; i < buffer.getReadable(); i++) {
for(int i = 0; i < static_cast<int>(buffer.getReadable()); i++) {
if(buff[i] == PB_START) {
if(i + 1 >= buffer.getReadable()) {
if(i + 1 >= static_cast<int>(buffer.getReadable())) {
return false; // 包不完整
}
pack_len = getInt32FromNetByte(buff[i + 1]);
end_index = pack_len + i - 1;
if(end_index >= buffer.getReadable()) {
if(end_index >= static_cast<int>(buffer.getReadable())) {
continue;
}
@ -144,7 +144,7 @@ namespace tinyrpc {
cur_index = cur_index + pbdata.msg_req_len;
if (cur_index > end_index || cur_index + sizeof(int32_t) - 1 > end_index) {
if (cur_index > end_index || cur_index + static_cast<int>(sizeof(int32_t)) - 1 > end_index) {
return false;
}
@ -167,7 +167,7 @@ namespace tinyrpc {
cur_index = cur_index + pbdata.service_name_len;
if(cur_index > end_index || cur_index + sizeof(int32_t) - 1 > end_index) {
if(cur_index > end_index || cur_index + static_cast<int>(sizeof(int32_t)) - 1 > end_index) {
return false;
}
@ -175,7 +175,7 @@ namespace tinyrpc {
cur_index = cur_index + sizeof(int32_t);
if(cur_index > end_index || cur_index + sizeof(int32_t) - 1 > end_index) {
if(cur_index > end_index || cur_index + static_cast<int>(sizeof(int32_t)) - 1 > end_index) {
return false;
}
@ -205,7 +205,9 @@ namespace tinyrpc {
pbdata.pb_data = std::string(&buff[cur_index], pb_data_len);
cur_index += pb_data_len;
buffer.readOffset(cur_index - start_index);
return true;

View File

@ -2,11 +2,13 @@
#include "logger.hpp"
#include "tinypb_data.hpp"
#include "error_code.hpp"
#include <cstddef>
#include <memory>
#include <sstream>
namespace tinyrpc {
TinypbDispatcher::TinypbDispatcher() {}
// TODO
TinypbDispatcher::~TinypbDispatcher() {
}
@ -30,7 +32,7 @@ namespace tinyrpc {
auto it = m_service_map.find(service_name);
if (it == m_service_map.end() || !((*it).second)) {
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 << "]";
@ -41,7 +43,42 @@ namespace tinyrpc {
Service* service = it->second;
const google::protobuf::MethodDescriptor* method = service->GetDescriptor()->FindMethodByName(method_name);
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(pbdata.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->GetRequestPrototype(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();
}
};
service->CallMethod(method, nullptr, requestMsg.get(), respondMsg.get(), nullptr /* callback */);
}
bool TinypbDispatcher::parseServiceFullName(const std::string& name, std::string& serviceName, std::string& methodName) {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
syntax = "proto2";
package tutorial;
message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;
enum PhoneType {
PHONE_TYPE_UNSPECIFIED = 0;
PHONE_TYPE_MOBILE = 1;
PHONE_TYPE_HOME = 2;
PHONE_TYPE_WORK = 3;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = PHONE_TYPE_HOME];
}
repeated PhoneNumber phones = 4;
}
message AddressBook {
repeated Person people = 1;
}

View File

93
test/protobuftest/main.cc Normal file
View File

@ -0,0 +1,93 @@
#include <iostream>
#include <fstream>
#include <string>
#include "addressbook.pb.h"
using namespace std;
// This function fills in a Person message based on user input.
void PromptForAddress(tutorial::Person* person) {
cout << "Enter person ID number: ";
int id;
cin >> id;
person->set_id(id);
cin.ignore(256, '\n');
cout << "Enter name: ";
getline(cin, *person->mutable_name());
cout << "Enter email address (blank for none): ";
string email;
getline(cin, email);
if (!email.empty()) {
person->set_email(email);
}
while (true) {
cout << "Enter a phone number (or leave blank to finish): ";
string number;
getline(cin, number);
if (number.empty()) {
break;
}
tutorial::Person::PhoneNumber* phone_number = person->add_phones();
phone_number->set_number(number);
cout << "Is this a mobile, home, or work phone? ";
string type;
getline(cin, type);
if (type == "mobile") {
phone_number->set_type(tutorial::Person::PHONE_TYPE_MOBILE);
} else if (type == "home") {
phone_number->set_type(tutorial::Person::PHONE_TYPE_HOME);
} else if (type == "work") {
phone_number->set_type(tutorial::Person::PHONE_TYPE_WORK);
} else {
cout << "Unknown phone type. Using default." << endl;
}
}
}
// Main function: Reads the entire address book from a file,
// adds one person based on user input, then writes it back out to the same
// file.
int main(int argc, char* argv[]) {
// Verify that the version of the library that we linked against is
// compatible with the version of the headers we compiled against.
GOOGLE_PROTOBUF_VERIFY_VERSION;
if (argc != 2) {
cerr << "Usage: " << argv[0] << " ADDRESS_BOOK_FILE" << endl;
return -1;
}
tutorial::AddressBook address_book;
{
// Read the existing address book.
fstream input(argv[1], ios::in | ios::binary);
if (!input) {
cout << argv[1] << ": File not found. Creating a new file." << endl;
} else if (!address_book.ParseFromIstream(&input)) {
cerr << "Failed to parse address book." << endl;
return -1;
}
}
// Add an address.
PromptForAddress(address_book.add_people());
{
// Write the new address book back to disk.
fstream output(argv[1], ios::out | ios::trunc | ios::binary);
if (!address_book.SerializeToOstream(&output)) {
cerr << "Failed to write address book." << endl;
return -1;
}
}
// Optional: Delete all global objects allocated by libprotobuf.
google::protobuf::ShutdownProtobufLibrary();
return 0;
}

BIN
test/protobuftest/my_program Executable file

Binary file not shown.

1
third_party/abseil-cpp vendored Submodule

@ -0,0 +1 @@
Subproject commit d7aaad83b488fd62bd51c81ecf16cd938532cc0a