rpc 部分逻辑 未完成
This commit is contained in:
parent
df8789f6c6
commit
9d9fb69cbb
@ -2,11 +2,13 @@ cmake_minimum_required(VERSION 3.0)
|
|||||||
|
|
||||||
project(tinyrpc)
|
project(tinyrpc)
|
||||||
|
|
||||||
# set(CMAKE_CXX_STANDARD 14)
|
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
enable_language(CXX ASM)
|
enable_language(CXX ASM)
|
||||||
|
|
||||||
add_compile_options(-g -Wall -std=c++17)
|
add_compile_options(-g -Wall)
|
||||||
|
|
||||||
include_directories(includes/coroutine)
|
include_directories(includes/coroutine)
|
||||||
include_directories(includes/log)
|
include_directories(includes/log)
|
||||||
@ -14,6 +16,7 @@ include_directories(includes/net)
|
|||||||
include_directories(includes/net/tcp)
|
include_directories(includes/net/tcp)
|
||||||
include_directories(includes/net/tinypb)
|
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/coroutine COROUTINE_SRC_LIST)
|
||||||
aux_source_directory(${CMAKE_SOURCE_DIR}/src/net NET_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)
|
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
|
add_library(tinyrpc
|
||||||
|
# ${SRC_LIST}
|
||||||
${COROUTINE_SRC_LIST}
|
${COROUTINE_SRC_LIST}
|
||||||
${TCP_SRC_LIST}
|
${TCP_SRC_LIST}
|
||||||
${NET_SRC_LIST}
|
${NET_SRC_LIST}
|
||||||
@ -43,6 +47,53 @@ add_executable(test_tinyrpc
|
|||||||
${TEST_SRC_LIST}
|
${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 PRIVATE tinyrpc)
|
||||||
target_link_libraries(test_tinyrpc PUBLIC protobuf)
|
|
||||||
target_link_libraries(test_tinyrpc PUBLIC stdc++)
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,6 +10,8 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
class TinypbDispatcher : public AbstractDispatcher {
|
class TinypbDispatcher : public AbstractDispatcher {
|
||||||
using Service = google::protobuf::Service;
|
using Service = google::protobuf::Service;
|
||||||
|
using Method = google::protobuf::MethodDescriptor;
|
||||||
|
using Message = google::protobuf::Message;
|
||||||
public:
|
public:
|
||||||
TinypbDispatcher();
|
TinypbDispatcher();
|
||||||
~TinypbDispatcher();
|
~TinypbDispatcher();
|
||||||
|
@ -275,3 +275,5 @@ namespace tinyrpc {
|
|||||||
t_reactor = nullptr;
|
t_reactor = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -138,6 +138,8 @@ namespace tinyrpc {
|
|||||||
std::unique_ptr<AbstractData> resp(new TinypbData);
|
std::unique_ptr<AbstractData> resp(new TinypbData);
|
||||||
m_server.getDispatcher().dispatcher(*this, *data, *resp);
|
m_server.getDispatcher().dispatcher(*this, *data, *resp);
|
||||||
|
|
||||||
|
m_server.getCoder().encoder(m_writeBuffer, *resp);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
static const char PB_START = 0x02; // start char
|
static const char PB_START = 0x02; // start char
|
||||||
static const char PB_END = 0x03; // end 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() {
|
TinypbCoder::TinypbCoder() {
|
||||||
// TODO
|
// TODO
|
||||||
@ -79,7 +79,7 @@ namespace tinyrpc {
|
|||||||
buf[cur_index++] = PB_END;
|
buf[cur_index++] = PB_END;
|
||||||
|
|
||||||
memcpy(buffer.getWriteAddress(), buf.get(), pk_len);
|
memcpy(buffer.getWriteAddress(), buf.get(), pk_len);
|
||||||
|
buffer.writeOffset(pk_len);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -93,17 +93,17 @@ namespace tinyrpc {
|
|||||||
bool isFullPack = false;
|
bool isFullPack = false;
|
||||||
int pack_len = -1;
|
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(buff[i] == PB_START) {
|
||||||
|
|
||||||
if(i + 1 >= buffer.getReadable()) {
|
if(i + 1 >= static_cast<int>(buffer.getReadable())) {
|
||||||
return false; // 包不完整
|
return false; // 包不完整
|
||||||
}
|
}
|
||||||
|
|
||||||
pack_len = getInt32FromNetByte(buff[i + 1]);
|
pack_len = getInt32FromNetByte(buff[i + 1]);
|
||||||
end_index = pack_len + i - 1;
|
end_index = pack_len + i - 1;
|
||||||
|
|
||||||
if(end_index >= buffer.getReadable()) {
|
if(end_index >= static_cast<int>(buffer.getReadable())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
cur_index = cur_index + pbdata.msg_req_len;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
cur_index = cur_index + pbdata.service_name_len;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
cur_index = cur_index + sizeof(int32_t);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,7 +205,9 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
|
|
||||||
pbdata.pb_data = std::string(&buff[cur_index], pb_data_len);
|
pbdata.pb_data = std::string(&buff[cur_index], pb_data_len);
|
||||||
|
cur_index += pb_data_len;
|
||||||
|
|
||||||
|
buffer.readOffset(cur_index - start_index);
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -2,11 +2,13 @@
|
|||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
#include "tinypb_data.hpp"
|
#include "tinypb_data.hpp"
|
||||||
#include "error_code.hpp"
|
#include "error_code.hpp"
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
namespace tinyrpc {
|
namespace tinyrpc {
|
||||||
TinypbDispatcher::TinypbDispatcher() {}
|
TinypbDispatcher::TinypbDispatcher() {}
|
||||||
// TODO
|
|
||||||
TinypbDispatcher::~TinypbDispatcher() {
|
TinypbDispatcher::~TinypbDispatcher() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -30,7 +32,7 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
auto it = m_service_map.find(service_name);
|
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;
|
respond.err_code = ERROR_SERVICE_NOT_FOUND;
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "not found service_name:[" << service_name << "]";
|
ss << "not found service_name:[" << service_name << "]";
|
||||||
@ -41,7 +43,42 @@ namespace tinyrpc {
|
|||||||
|
|
||||||
Service* service = it->second;
|
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) {
|
bool TinypbDispatcher::parseServiceFullName(const std::string& name, std::string& serviceName, std::string& methodName) {
|
||||||
|
1051
test/protobuftest/addressbook.pb.cc
Normal file
1051
test/protobuftest/addressbook.pb.cc
Normal file
File diff suppressed because it is too large
Load Diff
1196
test/protobuftest/addressbook.pb.h
Normal file
1196
test/protobuftest/addressbook.pb.h
Normal file
File diff suppressed because it is too large
Load Diff
27
test/protobuftest/addressbook.proto
Normal file
27
test/protobuftest/addressbook.proto
Normal 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;
|
||||||
|
}
|
0
test/protobuftest/err.info
Normal file
0
test/protobuftest/err.info
Normal file
93
test/protobuftest/main.cc
Normal file
93
test/protobuftest/main.cc
Normal 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
BIN
test/protobuftest/my_program
Executable file
Binary file not shown.
1
third_party/abseil-cpp
vendored
Submodule
1
third_party/abseil-cpp
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit d7aaad83b488fd62bd51c81ecf16cd938532cc0a
|
Loading…
Reference in New Issue
Block a user