什么是rpc
RPC(Remote Procedure Call),远程过程调用,它把网络交互类比为client调用server上的函数。RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。为实现该目标,RPC 框架需提供一种透明调用机制,让使用者不必显式的区分本地调用和远程调用。
srpc特点
- 序列化方案用的是protobuf
 - 服务器端采用workflow:每当有客户端调用时,服务端会创建一个特殊的任务,其基本工作和回调是分开的
 - 代理模式
 
安装
protobuf的安装
git clone -b 3.20.x https://github.com/protocolbuffers/protobuf.git protobuf.3.20
cd protobuf.3.20
sh autogen.sh
./configure
make
make install
 
srpc的安装
安装srpc的前置条件是要先安装 protbuf ,之后再来安装 srpc
git clone --recursive https://github.com/sogou/srpc.git
cd srpc
make
make install
 
快速开始
proto文件编写
syntax = "proto3";
message EchoRequest {
    string message = 1;
    string name = 2;
};
message EchoResponse {
    string message = 1;
};
service Example {
    rpc Echo(EchoRequest) returns (EchoResponse);
};
 
生成srpc代码
protoc example.proto --cpp_out=./ --proto_path=./
srpc_generator protobuf ./example.proto ./
 
输出
从中可以看出主要是生成了./srpc_test.srpc.h文件和 服务端文件./server.pb_skeleton.cc和客户端文件./client.pb_skeleton.cc
[Generator Begin]
proto file: [/home/xf/projects/test/./srpc_test.proto]
Successfully parse service block [message] : EchoRequest
Successfully parse service block [message] : EchoResponse
Successfully parse service block [service] : Example
Successfully parse method:Echo req:EchoRequest resp:EchoResponse
finish parsing proto file: [/home/xf/projects/test/./srpc_test.proto]
[Generator] generate srpc files: ./srpc_test.srpc.h 
[Generator Done]
[Generator] generate server files: ./server.pb_skeleton.cc, client files: ./client.pb_skeleton.cc
[Generator Done]
 
生成文件一窥
服务端代码
可以看出srpc服务端还是很简单的,只需要继承Service类重写Echo方法即可
/*
 * Server codes
 * Generated by SRPC
 */
class Service : public srpc::RPCService
{
public:
	// please implement these methods in server.cc
	virtual void Echo(EchoRequest *request, EchoResponse *response,
					srpc::RPCContext *ctx) = 0;
public:
	Service();
};
 
客户端代码
客户端相对来说要多很多内容
Echo同步调用async_Echo异步调用create_Echo_task通过workflow的方式调用
/*
 * Client codes
 * Generated by SRPC
 */
using EchoDone = std::function<void (EchoResponse *, srpc::RPCContext *)>;
class SRPCClient : public srpc::SRPCClient
{
public:
	void Echo(const EchoRequest *req, EchoDone done);
	void Echo(const EchoRequest *req, EchoResponse *resp, srpc::RPCSyncContext *sync_ctx);
	WFFuture<std::pair<EchoResponse, srpc::RPCSyncContext>> async_Echo(const EchoRequest *req);
public:
	SRPCClient(const char *host, unsigned short port);
	SRPCClient(const struct srpc::RPCClientParams *params);
public:
	srpc::SRPCClientTask *create_Echo_task(EchoDone done);
};
 
还能看见srpc除了提供workflow的方式,还提供了http,brpc,trpc,trpchttp等方式调用

服务端示例代码
#include <stdio.h>
#include <signal.h>
#include "example.srpc.h"
using namespace srpc;
class ExampleServiceImpl : public Example::Service
{
public:
    void Echo(EchoRequest *request, EchoResponse *response, RPCContext *ctx) override
    {
        response->set_message("Hi, " + request->name());
        printf("get_req:\n%s\nset_resp:\n%s\n",
                request->DebugString().c_str(), response->DebugString().c_str());
    }
};
void sig_handler(int signo) { }
int main()
{
    signal(SIGINT, sig_handler);
    signal(SIGTERM, sig_handler);
    SRPCServer server_tcp;
    SRPCHttpServer server_http;
    ExampleServiceImpl impl;
    server_tcp.add_service(&impl);
    server_http.add_service(&impl);
    server_tcp.start(1412);
    server_http.start(8811);
    getchar(); // press "Enter" to end.
    server_http.stop();
    server_tcp.stop();
    return 0;
}
 
客户端示例代码
#include <stdio.h>
#include "example.srpc.h"
using namespace srpc;
int main()
{
    Example::SRPCClient client("127.0.0.1", 1412);
    EchoRequest req;
    req.set_message("Hello, srpc!");
    req.set_name("workflow");
    client.Echo(&req, [](EchoResponse *response, RPCContext *ctx) {
        if (ctx->success())
            printf("%s\n", response->DebugString().c_str());
        else
            printf("status[%d] error[%d] errmsg:%s\n",
                    ctx->get_status_code(), ctx->get_error(), ctx->get_errmsg());
    });
    getchar(); // press "Enter" to end.
    return 0;
}
 
编译示例
g++ -o server server.cc example.pb.cc -std=c++11 -lsrpc
g++ -o client client.cc example.pb.cc -std=c++11 -lsrpc
 
运行
./server
./client
#server
get_req:
message: "Hello, srpc!"
name: "workflow"
set_resp:
message: "Hi, workflow"
#client
message: "Hi, workflow"
                





![[vscode]使用cmake时将命令行参数传递给调试目标](https://img-blog.csdnimg.cn/direct/1949876c1cb74d81b41dd1df671864d7.png)












