├── .gitignore ├── .gitmodules ├── TODO ├── ucorf ├── option.h ├── ucorf.h ├── preheader.h ├── hprose │ ├── hprose_message.h │ ├── hprose_message.cpp │ ├── hprose_header.h │ ├── hprose_header.cpp │ ├── hprose_service.cpp │ ├── hprose_service.h │ └── hprose_protocol.h ├── url.h ├── server_register.h ├── service.h ├── pb_message.h ├── pb_message.cpp ├── error.h ├── server.h ├── client.h ├── pb_service.h ├── server.cpp ├── server_register.cpp ├── client.cpp ├── error.cpp ├── transport.h ├── pb_service.cpp ├── net_transport.h ├── server_impl.h ├── dispatcher.h ├── message.h ├── server_finder.h ├── conhash.h ├── zookeeper.h ├── message.cpp ├── dispatcher.cpp ├── logger.h ├── client_impl.h ├── logger.cpp ├── net_transport.cpp ├── server_impl.cpp ├── server_finder.cpp ├── client_impl.cpp └── zookeeper.cpp ├── test ├── echo.proto ├── hprose_client.cpp ├── server.cpp ├── hprose_server.cpp ├── zk_client.cpp ├── CMakeLists.txt ├── client.cpp ├── zk_server.cpp ├── bmserver.cpp ├── hprose_bmserver.cpp ├── wnd_client.cpp ├── hprose_bmclient.cpp └── bmclient.cpp ├── samples ├── sample1_server.cpp ├── sample3_client.cpp ├── sample2_server.cpp ├── sample1_client.cpp ├── sample3_server.cpp ├── CMakeLists.txt ├── sample2_client.cpp └── sample4_client.cpp ├── CMakeLists.txt ├── README.md └── proto_gen ├── protoc-gen-rpc ├── plugin_pb2.py ├── plugin.proto └── descriptor.proto /.gitignore: -------------------------------------------------------------------------------- 1 | build/* 2 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "third_party/libgonet"] 2 | path = third_party/libgonet 3 | url = https://github.com/yyzybb537/libgonet.git 4 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | TODO: 2 | 提供查询RPC直接的srv和interface功能 3 | 提供rpc接口版本号校验, 检验interface签名 4 | 5 | DONE: 6 | 增加调试log模块, 输出链接相关信息 7 | 解决并发超过500导致的频繁错误问题(内核参数导致的问题) 8 | ZK服务注册与发现 9 | single client的retry bug. 10 | 一致性hash负载均衡 11 | 增加过载保护机制 12 | Log模块的reopen改为线程安全 13 | -------------------------------------------------------------------------------- /ucorf/option.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | 5 | namespace ucorf 6 | { 7 | struct Option 8 | { 9 | std::size_t request_wnd_size = -1; 10 | int rcv_timeout_ms = 10000; 11 | boost::any transport_opt; 12 | }; 13 | 14 | } //namespace ucorf 15 | -------------------------------------------------------------------------------- /test/echo.proto: -------------------------------------------------------------------------------- 1 | package Echo; 2 | 3 | option cc_generic_services = true; 4 | 5 | message EchoRequest 6 | { 7 | required int32 code = 1; 8 | }; 9 | 10 | message EchoResponse 11 | { 12 | required int32 code = 1; 13 | }; 14 | 15 | service EchoService 16 | { 17 | rpc Echo(EchoRequest) returns(EchoResponse); 18 | }; 19 | -------------------------------------------------------------------------------- /ucorf/ucorf.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | #include "message.h" 5 | #include "pb_message.h" 6 | #include "error.h" 7 | #include "logger.h" 8 | #include "option.h" 9 | #include "dispatcher.h" 10 | #include "transport.h" 11 | #include "net_transport.h" 12 | #include "server_finder.h" 13 | #include "server_register.h" 14 | #include "service.h" 15 | #include "pb_service.h" 16 | #include "zookeeper.h" 17 | #include "conhash.h" 18 | #include "server.h" 19 | #include "client.h" 20 | 21 | -------------------------------------------------------------------------------- /ucorf/preheader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // linux 18 | #include 19 | 20 | namespace ucorf 21 | { 22 | using boost_ec = ::boost::system::error_code; 23 | 24 | } //namespace ucorf 25 | -------------------------------------------------------------------------------- /ucorf/hprose/hprose_message.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | #include "message.h" 5 | #include 6 | 7 | namespace ucorf 8 | { 9 | class Hprose_Message : public IMessage 10 | { 11 | public: 12 | Hprose_Message() = default; 13 | explicit Hprose_Message(std::string const& body); 14 | 15 | virtual bool Serialize(void* buf, std::size_t len); 16 | virtual std::size_t ByteSize(); 17 | virtual std::size_t Parse(const void* buf, std::size_t len); 18 | 19 | std::string body_; 20 | }; 21 | } //namespace ucorf 22 | -------------------------------------------------------------------------------- /ucorf/url.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | 5 | namespace ucorf 6 | { 7 | class Url 8 | { 9 | public: 10 | enum class eProto 11 | { 12 | tcp, 13 | tls, 14 | udp, 15 | http, 16 | https, 17 | zookeeper, 18 | }; 19 | 20 | eProto proto_; 21 | std::string ori_address_; 22 | std::vector> address_; 23 | std::string path_; 24 | 25 | explicit Url(std::string const& str); 26 | }; 27 | 28 | } //namespace ucorf 29 | -------------------------------------------------------------------------------- /ucorf/hprose/hprose_message.cpp: -------------------------------------------------------------------------------- 1 | #include "hprose_message.h" 2 | 3 | namespace ucorf { 4 | 5 | Hprose_Message::Hprose_Message(std::string const& body) 6 | : body_(body) 7 | { 8 | } 9 | bool Hprose_Message::Serialize(void * buf, std::size_t len) 10 | { 11 | if (len < ByteSize()) return false; 12 | memcpy(buf, body_.data(), len); 13 | return true; 14 | } 15 | std::size_t Hprose_Message::ByteSize() 16 | { 17 | return body_.size(); 18 | } 19 | std::size_t Hprose_Message::Parse(const void * buf, std::size_t len) 20 | { 21 | body_.assign((const char*)buf, len); 22 | return len; 23 | } 24 | 25 | } //namespace ucorf 26 | -------------------------------------------------------------------------------- /ucorf/server_register.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | 5 | namespace ucorf 6 | { 7 | class IServerRegister 8 | { 9 | public: 10 | virtual ~IServerRegister() {} 11 | 12 | virtual bool Register(std::string url, std::string srv_info) = 0; 13 | 14 | virtual void Unregister() = 0; 15 | }; 16 | 17 | class ZookeeperRegister : public IServerRegister 18 | { 19 | public: 20 | virtual bool Register(std::string url, std::string srv_info); 21 | 22 | virtual void Unregister(); 23 | 24 | private: 25 | std::multimap destinations_; 26 | }; 27 | 28 | } //namespace ucorf 29 | -------------------------------------------------------------------------------- /ucorf/service.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | #include "message.h" 5 | 6 | namespace ucorf 7 | { 8 | class IMessage; 9 | class IService 10 | { 11 | public: 12 | virtual ~IService() {} 13 | 14 | virtual std::string name() = 0; 15 | 16 | virtual std::unique_ptr CallMethod(std::string const& method, 17 | const char *request_data, size_t request_bytes) = 0; 18 | }; 19 | 20 | class Client; 21 | class IServiceStub 22 | { 23 | public: 24 | explicit IServiceStub(Client * c) : c_(c) {} 25 | 26 | virtual ~IServiceStub() {} 27 | 28 | virtual std::string name() = 0; 29 | 30 | protected: 31 | Client * c_; 32 | }; 33 | 34 | } //namespace ucorf 35 | -------------------------------------------------------------------------------- /ucorf/pb_message.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "preheader.h" 4 | #include "message.h" 5 | #include 6 | #include 7 | 8 | namespace ucorf 9 | { 10 | class Pb_Message : public IMessage 11 | { 12 | Pb_Message(Pb_Message const&) = delete; 13 | Pb_Message& operator=(Pb_Message const&) = delete; 14 | 15 | public: 16 | Pb_Message() = default; 17 | Pb_Message(::google::protobuf::Message* msg, bool own = true); 18 | Pb_Message(std::unique_ptr<::google::protobuf::Message> && msg); 19 | ~Pb_Message(); 20 | 21 | virtual bool Serialize(void* buf, std::size_t len); 22 | virtual std::size_t ByteSize(); 23 | virtual std::size_t Parse(const void* buf, std::size_t len); 24 | 25 | ::google::protobuf::Message* msg_ = nullptr; 26 | bool own_ = false; 27 | }; 28 | } //namespace ucorf 29 | -------------------------------------------------------------------------------- /samples/sample1_server.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | * Sample1: 最简单的Server 3 | *********************************/ 4 | #include 5 | #include "echo.rpc.h" 6 | #include 7 | using namespace Echo; 8 | 9 | // 1.继承代码生成器生成的类,并重写定义的rpc接口 10 | struct MyEcho : public ::Echo::UcorfEchoService 11 | { 12 | virtual bool Echo(EchoRequest & request, EchoResponse & response) 13 | { 14 | // 处理请求 15 | response.set_code(request.code()); 16 | return true; 17 | } 18 | }; 19 | 20 | int main() 21 | { 22 | // 2.创建server对象 23 | ucorf::Server server; 24 | 25 | // 3.注册MyEcho服务 26 | server.RegisterService(boost::shared_ptr(new MyEcho)); 27 | 28 | // 4.启动监听端口 29 | ucorf::boost_ec ec = server.Listen("tcp://127.0.0.1:8080"); // 监听本机8080端口 30 | 31 | // 5.启动协程框架主循环 32 | co_sched.RunLoop(); 33 | 34 | return 0; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /samples/sample3_client.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | * Sample2: 从Zookeeper获取服务端地址的Client 3 | *********************************/ 4 | #include 5 | #include "echo.rpc.h" 6 | #include 7 | using namespace Echo; 8 | 9 | int main(int argc, char **argv) 10 | { 11 | // 1.创建Client对象 12 | ucorf::Client client; 13 | 14 | // 2.设置服务端注册的ZK地址和节点, 格式如下: 15 | client.SetUrl("zk://127.0.0.1:2181/ucorf/test"); 16 | 17 | // 3.创建Stub对象,并绑定Client 18 | UcorfEchoServiceStub stub(&client); 19 | 20 | // 4.启动一个协程 21 | go [&]{ 22 | co_sleep(500); 23 | 24 | // 5.构造RPC调用参数 25 | EchoRequest request; 26 | request.set_code(1); 27 | 28 | // 6.调用RPC接口 29 | std::shared_ptr rsp = stub.Echo(request); 30 | 31 | // 7.获取返回值 32 | std::cout << "Response: " << rsp->code() << endl; 33 | }; 34 | 35 | // 8.启动协程框架主循环 36 | co_sched.RunLoop(); 37 | return 0; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /samples/sample2_server.cpp: -------------------------------------------------------------------------------- 1 | /******************************** 2 | * Sample2: 同时监听多个端口的Server 3 | *********************************/ 4 | #include 5 | #include "echo.rpc.h" 6 | #include 7 | using namespace Echo; 8 | using namespace ucorf; 9 | 10 | // 1.继承代码生成器生成的类,并重写定义的rpc接口 11 | struct MyEcho : public ::Echo::UcorfEchoService 12 | { 13 | virtual bool Echo(EchoRequest & request, EchoResponse & response) 14 | { 15 | // 处理请求 16 | response.set_code(request.code()); 17 | return true; 18 | } 19 | }; 20 | 21 | int main() 22 | { 23 | // 2.创建server对象 24 | ucorf::Server server; 25 | 26 | // 3.注册MyEcho服务 27 | server.RegisterService(boost::shared_ptr(new MyEcho)); 28 | 29 | // 4.监听2个端口 30 | server.Listen("tcp://127.0.0.1:8080"); // 监听本机8080端口 31 | server.Listen("tcp://127.0.0.1:8081"); // 监听本机8081端口 32 | 33 | // 5.启动协程框架主循环 34 | co_sched.RunLoop(); 35 | 36 | return 0; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /ucorf/pb_message.cpp: -------------------------------------------------------------------------------- 1 | #include "pb_message.h" 2 | 3 | namespace ucorf 4 | { 5 | Pb_Message::Pb_Message(::google::protobuf::Message* msg, bool own) 6 | : msg_(msg), own_(own) 7 | { 8 | } 9 | 10 | Pb_Message::Pb_Message(std::unique_ptr<::google::protobuf::Message> && msg) 11 | : msg_(msg.release()), own_(true) 12 | { 13 | } 14 | 15 | Pb_Message::~Pb_Message() 16 | { 17 | if (own_ && msg_) 18 | delete msg_; 19 | } 20 | 21 | bool Pb_Message::Serialize(void* buf, std::size_t len) 22 | { 23 | if (!msg_) return false; 24 | return msg_->SerializeToArray(buf, len); 25 | } 26 | std::size_t Pb_Message::ByteSize() 27 | { 28 | if (!msg_) return 0; 29 | return msg_->ByteSize(); 30 | } 31 | std::size_t Pb_Message::Parse(const void* buf, std::size_t len) 32 | { 33 | if (!msg_) return 0; 34 | return msg_->ParseFromArray(buf, len); 35 | } 36 | 37 | } //namespace ucorf 38 | -------------------------------------------------------------------------------- /ucorf/hprose/hprose_header.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "message.h" 4 | 5 | namespace ucorf 6 | { 7 | struct Hprose_Head : public IHeader 8 | { 9 | public: 10 | virtual void SetId(std::size_t id); 11 | virtual void SetFollowBytes(std::size_t bytes); 12 | 13 | virtual void SetType(eHeaderType) {} 14 | virtual void SetService(std::string const&) {} 15 | virtual void SetMethod(std::string const&) {} 16 | 17 | virtual std::size_t GetId(); 18 | virtual eHeaderType GetType(); 19 | virtual std::size_t GetFollowBytes(); 20 | virtual std::string GetService(); 21 | virtual std::string GetMethod() { return ""; } 22 | 23 | virtual bool Serialize(void* buf, std::size_t len); 24 | virtual std::size_t ByteSize(); 25 | virtual std::size_t Parse(const void* buf, std::size_t len); 26 | 27 | static IHeaderPtr Factory(); 28 | 29 | uint32_t callid; 30 | uint32_t body_length; 31 | }; 32 | } //namespace ucorf 33 | -------------------------------------------------------------------------------- /ucorf/error.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace ucorf 7 | { 8 | 9 | using boost_ec = boost::system::error_code; 10 | 11 | enum class eUcorfErrorCode : int 12 | { 13 | ec_ok = 0, 14 | ec_snd_timeout = 1, 15 | ec_rcv_timeout = 2, 16 | ec_call_error = 3, 17 | ec_parse_error = 4, 18 | ec_no_estab = 5, 19 | ec_unsupport_protocol = 6, 20 | ec_req_wnd_full = 7, 21 | ec_logic_error = 8, 22 | }; 23 | 24 | class ucorf_error_category 25 | : public boost::system::error_category 26 | { 27 | public: 28 | virtual const char* name() const BOOST_SYSTEM_NOEXCEPT; 29 | 30 | virtual std::string message(int) const; 31 | }; 32 | 33 | const boost::system::error_category& GetUcorfErrorCategory(); 34 | 35 | boost_ec MakeUcorfErrorCode(eUcorfErrorCode code); 36 | 37 | void ThrowError(eUcorfErrorCode code, const char* what = ""); 38 | 39 | } //namespace ucorf 40 | -------------------------------------------------------------------------------- /ucorf/server.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "server_impl.h" 4 | 5 | namespace ucorf 6 | { 7 | class Server 8 | { 9 | public: 10 | typedef boost::function MessageFactory; 11 | 12 | Server(); 13 | 14 | Server& SetOption(boost::shared_ptr