All Projects → Ananfa → libcorpc

Ananfa / libcorpc

Licence: Apache-2.0 license
Libcorpc is a high performance coroutine base RPC framework

Programming Languages

C++
36643 projects - #6 most used programming language
C#
18002 projects
CMake
9771 projects
c
50402 projects - #5 most used programming language
assembly
5116 projects

Projects that are alternatives of or similar to libcorpc

Co
Art of C++. Flag, logging, unit-test, json, go-style coroutine and more.
Stars: ✭ 2,264 (+11220%)
Mutual labels:  rpc, coroutine, libco
cocoyaxi
A go-style coroutine library in C++11 and more.
Stars: ✭ 2,392 (+11860%)
Mutual labels:  rpc, coroutine, libco
Purerpc
Asynchronous pure Python gRPC client and server implementation supporting asyncio, uvloop, curio and trio
Stars: ✭ 125 (+525%)
Mutual labels:  rpc, rpc-framework
Ice
Comprehensive RPC framework with support for C++, C#, Java, JavaScript, Python and more.
Stars: ✭ 1,772 (+8760%)
Mutual labels:  rpc, rpc-framework
Doge
Doge is a high-performance, Python based, open source RPC framework
Stars: ✭ 144 (+620%)
Mutual labels:  rpc, rpc-framework
Jupiter
Jupiter是一款性能非常不错的, 轻量级的分布式服务框架
Stars: ✭ 1,372 (+6760%)
Mutual labels:  rpc, rpc-framework
Whatsmars
Java生态研究(Spring Boot + Redis + Dubbo + RocketMQ + Elasticsearch)🔥🔥🔥🔥🔥
Stars: ✭ 1,389 (+6845%)
Mutual labels:  rpc, rpc-framework
Hprose Js
Hprose is a cross-language RPC. This project is Hprose 2.0 RPC for JavaScript
Stars: ✭ 133 (+565%)
Mutual labels:  rpc, rpc-framework
Hprose Php
Hprose is a cross-language RPC. This project is Hprose 3.0 for PHP
Stars: ✭ 1,952 (+9660%)
Mutual labels:  rpc, rpc-framework
Rpc
Simple RPC style APIs with generated clients & servers.
Stars: ✭ 192 (+860%)
Mutual labels:  rpc, rpc-framework
Fpnn
Fast Programmable Nexus Network
Stars: ✭ 220 (+1000%)
Mutual labels:  rpc, rpc-framework
Hprose Delphi
Hprose is a cross-language RPC. This project is Hprose 2.0 for Delphi and FreePascal
Stars: ✭ 100 (+400%)
Mutual labels:  rpc, rpc-framework
Rpc.py
A fast and powerful RPC framework based on ASGI/WSGI.
Stars: ✭ 98 (+390%)
Mutual labels:  rpc, rpc-framework
Jrpc
JSON-RPC implementation in C++17
Stars: ✭ 113 (+465%)
Mutual labels:  rpc, rpc-framework
Gotree
Gotree is a vertically distributed framework. Gotree's goal is to easily develop distributed services and liberate the mental burden of developers.
Stars: ✭ 91 (+355%)
Mutual labels:  rpc, rpc-framework
Easyrpc
EasyRpc is a simple, high-performance, easy-to-use RPC framework based on Netty, ZooKeeper and ProtoStuff.
Stars: ✭ 79 (+295%)
Mutual labels:  rpc, rpc-framework
jigsaw-rpc
jigsaw-rpc is an RPC framework written in TypeScript under Node.js
Stars: ✭ 14 (-30%)
Mutual labels:  rpc, rpc-framework
Rpcx Java
rpcx implementation in Java for server side and client side
Stars: ✭ 71 (+255%)
Mutual labels:  rpc, rpc-framework
Rsf
已作为 Hasor 的子项目,迁移到:http://git.oschina.net/zycgit/hasor
Stars: ✭ 77 (+285%)
Mutual labels:  rpc, rpc-framework
Goworld
Scalable Distributed Game Server Engine with Hot Swapping in Golang
Stars: ✭ 2,007 (+9935%)
Mutual labels:  rpc, game-server

libcorpc

  • Libcorpc is a high performance coroutine base RPC framework.
  • Libcorpc is developed base on Tencent's libco(Some change has been maked to the libco and the changed source of libco is in the co directory).
  • Using Google's protobuf to define RPC service.
  • Send/Recv are handle in different IO threads, and multiple RPC requests can be send at the same times.
  • Libcorpc support interprocess and innerprocess RPC.
  • Libcorpc support not only RPC service but also TCP/UDP message service.
  • Libcorpc provide connect-pool access to MySQL/MongoDB/Redis/Memcached.
  • Libcorpc can build in macOS and Linux.

Architecture

Alt Architecture


Proto

  • Using google protobuf 2.6.1
  • corpc_option.proto (It need to be imported from rpc service proto files)
import "google/protobuf/descriptor.proto";

package corpc;

extend google.protobuf.ServiceOptions {
    optional uint32 global_service_id = 10000;  // define service id
}

extend google.protobuf.MethodOptions {
    optional bool need_coroutine = 10002;       // start new coroutine to call the method
    optional bool not_care_response = 10003;    // care response or not
    optional uint32 timeout = 10004;            // rpc timeout duration, 0 means infinity
}

message Void {}

HelloWorld

This example shows a simple way using libcorpc to develop. There are three files in the example: helloworld.proto, server.cpp and client.cpp.

  • helloworld.proto
import "corpc_option.proto";

option cc_generic_services = true;

message FooRequest {
    required string msg1 = 1;
    required string msg2 = 2;
}

message FooResponse {
    required string msg = 1;
}

service HelloWorldService {
    option (corpc.global_service_id) = 1;

    rpc foo(FooRequest) returns(FooResponse);
}

The "helloworld.proto" file define a rpc service "HelloWorldService" with a rpc method "foo". The method has an argument with "FooRequest" message type and the return value type is "FooResponse"

  • server.cpp
#include "corpc_routine_env.h"
#include "corpc_rpc_server.h"

#include "helloworld.pb.h"

using namespace corpc;

class HelloWorldServiceImpl : public HelloWorldService {
public:
    HelloWorldServiceImpl() {}
    virtual void foo(::google::protobuf::RpcController* controller,
                     const ::FooRequest* request,
                     ::FooResponse* response,
                     ::google::protobuf::Closure* done) {
        std::string msg1 = request->msg1();
        std::string msg2 = request->msg2();
        
        response->set_msg(msg1 + " " + msg2);
    }
};

int main(int argc, const char * argv[]) {
    co_start_hook();
    
    if(argc<3){
        LOG("Usage:\n"
               "HelloWorldServer [IP] [PORT]\n");
        return -1;
    }
    
    std::string ip = argv[1];
    unsigned short int port = atoi(argv[2]);
    
    IO *io = IO::create(1, 1); // create IO layer for recv&send
    
    RpcServer *server = RpcServer::create(io, 0, ip, port);
    
    HelloWorldServiceImpl *helloWorldService = new HelloWorldServiceImpl();
    server->registerService(helloWorldService);
    
    RoutineEnvironment::runEventLoop();
}

The "server.cpp" file is a server implementation which show how to implement a rpc server. The server implementation create a IO object before create the RpcServer object. The IO object is responsible for recv and send data efficiently. The RpcServer is responsible for providing rpc service in certain address by register a rpc service (HelloWorldServiceImpl) to the RpcServer. The "HelloWorldServiceImpl" class implement HelloWorldService, it combine msg1 and msg2 string from the request and return result by the response.

  • client.cpp
#include "corpc_routine_env.h"
#include "corpc_rpc_client.h"
#include "corpc_controller.h"
#include "helloworld.pb.h"

using namespace corpc;

static void *helloworld_routine( void *arg )
{
    co_enable_hook_sys();
    
    HelloWorldService::Stub *helloworld_clt = (HelloWorldService::Stub *)arg;
    
    FooRequest *request = new FooRequest();
    FooResponse *response = new FooResponse();
    Controller *controller = new Controller();
    
    request->set_msg1("Hello");
    request->set_msg2("World");
    
    helloworld_clt->foo(controller, request, response, NULL);
    
    if (controller->Failed()) {
        ERROR_LOG("Rpc Call Failed : %s\n", controller->ErrorText().c_str());
    } else {
        LOG(response->msg().c_str());
    }
    
    delete controller;
    delete response;
    delete request;
    
    return NULL;
}

int main(int argc, const char * argv[]) {
    co_start_hook();
    
    if(argc<3){
        LOG("Usage:\n"
               "HelloWorldClient [HOST] [PORT] [NUM]\n");
        return -1;
    }
    
    std::string host = argv[1];
    unsigned short int port = atoi(argv[2]);
    
    IO *io = IO::create(1, 1); // create IO layer for recv&send
    
    RpcClient *client = RpcClient::create(io);
    RpcClient::Channel *channel = new RpcClient::Channel(client, host, port, 1);
    HelloWorldService::Stub *helloworld_clt = new HelloWorldService::Stub(channel);
    
    RoutineEnvironment::startCoroutine(helloworld_routine, helloworld_clt);
    
    RoutineEnvironment::runEventLoop();
}

The "client.cpp" file is the client side implementation which show how to call rpc server from rpc client. The client implementation also create an IO object, a RpcClient base on the IO object, a rpc channal connect to the rpc server and then create the service stub object base on the rpc channel. The rpc method "foo" can be call by the stub object. In this example it create a coroutine to call rpc.


tutorial

  • Tutorial1: a simple hello world example
  • Tutorial2: add a middle RPC server on the base of Tutorial1
  • Tutorial3: show how to use the "need_coroutine" option
  • Tutorial4: innerprocess RPC
  • Tutorial5: recursive RPC call between two RPC servers to calculate factorial value

benchmark

  • Environment:a MacBook Pro, macOS 10.12.6, cpu: 2.6GHz i5
  • Interprocess RPC benchmark:example/example_interRpc, average 75000+ rpc per second
  • Innerprocess RPC benchmark:example/example_innerRpc,average 200000+ rpc per second

build

  • Need GCC 4.8.3 or later
  • Need cmake(btw, 'libcorpc.xcworkspace' can be used In MacOS Xcode)
  • Install libco library
$ cd co && mkdir build && cd build && cmake .. && make install && cd ../..
  • Install libcorpc library(need libprotobuf 2.6)
$ cd corpc && mkdir build && cd build && cmake .. && make install && cd ../..
  • Base on needs install libcorpc_memcached library(need libmemcached 1.0)
$ cd corpc_memcached && mkdir build && cd build && cmake .. && make install && cd ../..
  • Base on needs install libcorpc_mongodb library(need libmongoc-1.0 and libbson-1.0)
$ cd corpc_mongodb && mkdir build && cd build && cmake .. && make install && cd ../..
  • Base on needs install libcorpc_redis library(need libhiredis)
$ cd corpc_redis && mkdir build && cd build && cmake .. && make install && cd ../..
  • Base on needs install libcorpc_mysql library(need libmysqlclient)
$ cd corpc_mysql && mkdir build && cd build && cmake .. && make install && cd ../..
  • Build tutorials
$ cd tutorial/tutorial1 && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd tutorial/tutorial2 && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd tutorial/tutorial3 && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd tutorial/tutorial4 && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd tutorial/tutorial5 && mkdir build && cd build && cmake .. && make && cd ../../..
  • Build Examples
$ cd example/example_interRpc && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_innerRpc && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_echoTcp && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_echoUdp && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_memcached && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_mongodb && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_mysql && mkdir build && cd build && cmake .. && make && cd ../../..
$ cd example/example_redis && mkdir build && cd build && cmake .. && make && cd ../../..

Notice

  • When using third party library(E.g. MySQL,MongoDB,Redis,Memcached,etc), add "LD_PRELOAD="(Linux) or “DYLD_INSERT_LIBRARIES= DYLD_FORCE_FLAT_NAMESPACE=y”(MacOS) to start program.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].