Giter Club home page Giter Club logo

ezrpc's Introduction

EzRpc

简单完成的远程函数级调用(跨主机或进程)服务接口封装方式(Head Only)

Quick Start(快速使用)

使用模版来进行统一化的服务入口选择,传参和返回值获取步骤,减小远程客户端调用的API封装和服务端之间的通信开发成本。

Server(服务端)

服务端需要建立一个服务入口,其不包含在本例子当中,本例假设通过AcceptRequest已经收到服务请求,并生成通信栈TestStack.
通过ez_rpc::bind建立一个动作代理对象ez_rpc::RpcServerProxyBase
并通过注入通信栈TestStack到其仿函数中来完成后续的函数参数接收调用和返回。

using rpc_type = enum {
    k_func_1 = 0,
    k_func_2 = 1,
    k_func_3 = 2,
};

int main(int argc,char* argv[])
{
    /**
     * 整个参数接收过程以及调用返回都封装到RpcBind中完成
     */
    TestStack stack = AcceptRequest(SERVER_NAME);

    if(stack)
    {
        /**
         * 获取rpc_type,明确调用函数
         */
        const rpc_type& symbol = ez_rpc::getArgs<0>(ez_rpc::RpcArgs<rpc_type>(stack));

        /**
         * 不同的函数声明形式使用switch做匹配,如果是统一抽象的函数接口,可以使用映射表来管理。
         * 也可以把stack注入进去,后面继续使用stack进行交互。
         */
        switch(symbol){
            case k_func_3:{
                ez_rpc::bind(
                    [](int a,float b,bool c)->int {printf("Args From client=>%d-%f-%s\n",a,b,c?"true":"false");return 0;}
                )(stack);
                break;
            }
            case k_func_2:{
                ez_rpc::bind(
                    [](float b,bool c)->int {printf("Args From client=>%f-%s\n",b,c?"true":"false");return 0;}
                )(stack);
                break;
            }
            case k_func_1:{
                ez_rpc::bind(
                    [](bool c)->int {printf("Args From client=>%s\n",c?"true":"false");return 0;}
                )(stack);
                break;
            }
        }
    }

    return 0;
}

调用端使用的SDK API封装(服务端提供功能调用的接口封装)

对应上一节服务端存在存在以下功能接口和调用约定:

int (*)(int a,float b,bool c);  // 调用功能约定k_func_1
int (*)(float b,bool c);        // 调用功能约定k_func_2
int (*)(bool c);                // 调用功能约定k_func_3

创建函数调用代理 ez_rpc::RpcCallProxy<T> 其中模版类型T返回值类型,构造函数形参为注入的通信栈和服务端函数调用约定标识(本例中即为枚举量, 通过调用代理的仿函数来直接进行传参,并获取返回值就和真实函数行为一样,通过异常捕获来获取通信过程中的异常。

以上步骤即可完成和服务端通信。

int api_3(int a,float b,bool c)
{
    int ret = 0;

    try{
        TestStack stack = TestStack(SERVER_NAME);
        ez_rpc::RpcCallProxy<int> proxy_func(stack,k_func_3);
        ret = proxy_func(a,b,c);
    }catch(ez_rpc::rpc_err_t err) {
        RPC_DBG("proxy rpc fun failed,err"<<err);
    }

    return ret;
}

int api_2(float b,bool c)
{
    int ret = 0;

    try{
        TestStack stack = TestStack(SERVER_NAME);
        ez_rpc::RpcCallProxy<int> proxy_func(stack,k_func_2);
        ret = proxy_func(b,c);
    }catch(ez_rpc::rpc_err_t err) {
        RPC_DBG("proxy rpc fun failed,err"<<err);
    }

    return ret;
}

int api_1(bool c)
{
    int ret = 0;

    try{
        TestStack stack = TestStack(SERVER_NAME);
        ez_rpc::RpcCallProxy<int> proxy_func(stack,k_func_1);
        ret = proxy_func(c);
    }catch(ez_rpc::rpc_err_t err) {
        RPC_DBG("proxy rpc fun failed,err"<<err);
    }

    return ret;
}

Stack(通信栈)

通过往客户代理对象和服务代理对象中注入ez_rpc::RpcStack来按需完成实际的参数和返回值通信操作。
ez_rpc::RpcStack已经封装了实际操作的文件描述符和判断描述符有效性的方法,其余方法允许继承动态重载,可替换以下几个函数:

  1. virtual bool getReturn(void* ret,unsigned int size);
  2. virtual bool popReturn(const void* ret,unsigned int size);
  3. virtual bool pushStack(void* ret,unsigned int size);
  4. virtual bool popStack(void* ret,unsigned int size);

Limit(限制)

远程调用限制:

  1. 被代理函数的形参必须是POD类型的数据,且为值传递.
    • 由于RPC调用限制,故参数为值传递
  2. 形参不能声明为数组,如char a[20]
    • 因为数组在模版化后会被转化为指针,可以将数组封装进结构体以解决此缺陷
  3. 参数大小需要考虑线程栈
    • 服务端接收的参数依然保存在栈中,不能大到栈溢出

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.