Skip to content

Commit 6ae20a7

Browse files
committed
rpc
1 parent a97323f commit 6ae20a7

File tree

12 files changed

+385
-85
lines changed

12 files changed

+385
-85
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ hook系统底层和socket相关的API,socket io相关的API,以及sleep系
136136
* [reactor架构](./docs/reactor.md)
137137
* [tcpServer](./docs/rpc/readme.md)
138138
* RPC
139-
* [RPC杂记](./docs/reactor.md)
139+
* [RPC 介绍](./docs/rpc/intro.md)
140+
* [RPC框架自上向下剖析](./docs/rpc/usage.md)
140141
* example解析
141142
* [文件传输](./examples/filetransfer/readme.md)
142143
* [聊天广播](./examples/chat/chat.md)
Lines changed: 55 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include "RpcProvider.h"
1+
#include "RpcServer.h"
22
#include "rpcHeader.pb.h"
33
#include <google/protobuf/descriptor.h>
44
#include "burger/net/Buffer.h"
@@ -8,10 +8,12 @@ using namespace burger::net;
88
using namespace burger::rpc;
99
using namespace std::placeholders;
1010

11-
// 这是框架提供给外部使用,可以发布rpc方法的函数接口
12-
// service_name --》 service描述 --》 service* 记录的服务对象
13-
// --》 method_name --> method 方法对象
14-
void RpcProvider::NotifyService(google::protobuf::Service *service) {
11+
namespace {
12+
const size_t kHeaderPrefixNum = 4;
13+
14+
} // namespace
15+
16+
void RpcServer::NotifyService(google::protobuf::Service *service) {
1517
ServiceInfo serviceInfo;
1618
// 获取了服务对象的描述信息
1719
const google::protobuf::ServiceDescriptor *serviceDescPtr = service->GetDescriptor();
@@ -31,65 +33,40 @@ void RpcProvider::NotifyService(google::protobuf::Service *service) {
3133
serviceInfoMap_.insert({serviceName, serviceInfo});
3234
}
3335

34-
// 启动rpc服务结点,开始提供rpc远程网络调用服务
35-
void RpcProvider::Run() {
36+
void RpcServer::Run() {
3637
std::string ip = Config::Instance().getString("rpc", "rpcServerIp", "127.0.0.1");
3738
uint16_t port = Config::Instance().getUInt16("rpc", "rpcServerPort", 8000);
3839
InetAddress addr(ip, port);
39-
CoTcpServer server(&sched_, addr, "RpcProvider");
40+
CoTcpServer server(&sched_, addr, "RpcServer");
4041

41-
server.setConnectionHandler(std::bind(&RpcProvider::connHandler, this, _1));
42+
server.setConnectionHandler(std::bind(&RpcServer::connHandler, this, _1));
4243
server.setThreadNum(4);
43-
INFO("RpcProvider start service at {} : {}", ip, port);
44+
INFO("RpcServer start service at {} : {}", ip, port);
4445
server.start();
4546
sched_.wait();
4647
}
4748

48-
// 框架内部,RpcProvider 和 RpcConsumer 协商好之间通信的protobuf数据类型
49-
// service_name method_name
50-
// 我们需要定义proto的message类型,进行数据头的序列化和反序列化
51-
// 发来字节流 : 16UserserviceMITSK123
52-
// header_size(4个字节) + header_str + args_str
53-
// 考虑粘包问题,所以我们不仅要记录service_name, method_name 还要记录 args_size
54-
// header_size 要存成二进制, 利用std::string 的copy
5549
// todo : 此处好好反复考虑粘包情况
56-
void RpcProvider::connHandler(const CoTcpConnection::ptr& conn) {
50+
void RpcServer::connHandler(const CoTcpConnection::ptr& conn) {
5751
Buffer::ptr buf = std::make_shared<Buffer>();
5852
while(conn->recv(buf) > 0) {
5953
// 网络上接受的远程rpc调用请求的字符流, Login args
6054
std::string recvStr = buf->retrieveAllAsString();
61-
// 从字节流中读取4个字节的内容
6255
uint32_t headerSize = 0;
63-
size_t headerPrefixNum = 4;
64-
recvStr.copy(reinterpret_cast<char *>(&headerSize), headerPrefixNum, 0);
65-
66-
// 根据headerSize读取数据头的原始字符流
67-
std::string rpcHeaderStr = recvStr.substr(headerPrefixNum, headerSize);
68-
// 反序列化数据,得到rpc请求的详细信息
69-
RpcHeader rpcHeader;
56+
std::string rpcHeaderStr = readHeader(recvStr, headerSize);
57+
7058
std::string serviceName;
7159
std::string methodName;
7260
uint32_t argsSize = 0;
73-
if(rpcHeader.ParseFromString(rpcHeaderStr)) {
74-
// 数据头反序列化成功
75-
serviceName = rpcHeader.servicename();
76-
methodName = rpcHeader.methodname();
77-
argsSize = rpcHeader.argssize();
78-
} else {
79-
// 数据头反序列化失败
80-
ERROR("rpcHeaderStr {} parse error", rpcHeaderStr);
81-
return;
82-
}
83-
// 获取rpc方法参数的字符流数据
84-
std::string argsStr = recvStr.substr(headerPrefixNum + headerSize, argsSize);
61+
if(!deserializeHeader(rpcHeaderStr, serviceName, methodName, argsSize)) return;
62+
63+
std::string argsStr = readArgs(recvStr, headerSize, argsSize);
8564
#ifdef DEBUG
86-
INFO("====================================");
87-
INFO("headerSize : {}", headerSize);
88-
INFO("rpcHeaderStr : {}", rpcHeaderStr);
89-
INFO("serviceName : {}", serviceName);
90-
INFO("methodName : {}", methodName);
91-
INFO("argsSize : {}", argsSize);
92-
INFO("====================================");
65+
DEBUG("headerSize : {}", headerSize);
66+
DEBUG("rpcHeaderStr : {}", rpcHeaderStr);
67+
DEBUG("serviceName : {}", serviceName);
68+
DEBUG("methodName : {}", methodName);
69+
DEBUG("argsSize : {}", argsSize);
9370
#endif
9471
// 获取service对象和method对象
9572
auto it = serviceInfoMap_.find(serviceName);
@@ -102,6 +79,7 @@ void RpcProvider::connHandler(const CoTcpConnection::ptr& conn) {
10279
if(mit == it->second.methodMap_.end()) {
10380
ERROR("method Name : {} dose not exist", methodName);
10481
}
82+
10583
google::protobuf::Service *service = it->second.service_; // 获取service对象 new UserService
10684
const google::protobuf::MethodDescriptor *method = mit->second; // 获取method对象 Login
10785

@@ -115,11 +93,11 @@ void RpcProvider::connHandler(const CoTcpConnection::ptr& conn) {
11593

11694
// 下面的method方法的调用,绑定一个Closure的回调函数
11795
// todo: 为何我们此处要手动去设置类型
118-
google::protobuf::Closure *done = google::protobuf::NewCallback<RpcProvider,
96+
google::protobuf::Closure *done = google::protobuf::NewCallback<RpcServer,
11997
const CoTcpConnection::ptr&,
12098
google::protobuf::Message *>
12199
(this,
122-
&RpcProvider::sendRpcResonse,
100+
&RpcServer::sendRpcResonse,
123101
conn, response);
124102
// 在框架上根据远端rpc请求,调用当前rpc节点上发布的方法
125103
// new UserService().Login(controller, request, response, done)
@@ -128,7 +106,7 @@ void RpcProvider::connHandler(const CoTcpConnection::ptr& conn) {
128106
}
129107

130108
// Closure 的回调操作,用于序列化rpc的响应和网络发送
131-
void RpcProvider::sendRpcResonse(const CoTcpConnection::ptr& conn, google::protobuf::Message* response) {
109+
void RpcServer::sendRpcResonse(const CoTcpConnection::ptr& conn, google::protobuf::Message* response) {
132110
std::string responseStr;
133111
if(response->SerializeToString(&responseStr)) { // response进行序列化
134112
// 序列化成功后,通过网络把rpc方法执行的结果发送回rpc的调用方
@@ -138,3 +116,32 @@ void RpcProvider::sendRpcResonse(const CoTcpConnection::ptr& conn, google::proto
138116
}
139117
conn->shutdown(); // 短连接,主动关闭
140118
}
119+
120+
std::string RpcServer::readHeader(const std::string& recvStr, uint32_t& headerSize) {
121+
// 从字节流中读取4个字节的内容
122+
// header_size 要存成二进制, 利用std::string 的copy
123+
recvStr.copy(reinterpret_cast<char *>(&headerSize), kHeaderPrefixNum, 0);
124+
// 根据headerSize读取数据头的原始字符流
125+
std::string rpcHeaderStr = recvStr.substr(kHeaderPrefixNum, headerSize);
126+
return rpcHeaderStr;
127+
}
128+
129+
bool RpcServer::deserializeHeader(const std::string& rpcHeaderStr, std::string& serviceName,
130+
std::string& methodName, uint32_t& argsSize) {
131+
RpcHeader rpcHeader;
132+
if(rpcHeader.ParseFromString(rpcHeaderStr)) {
133+
// 数据头反序列化成功
134+
serviceName = rpcHeader.servicename();
135+
methodName = rpcHeader.methodname();
136+
argsSize = rpcHeader.argssize();
137+
return true;
138+
} else {
139+
// 数据头反序列化失败
140+
ERROR("rpcHeaderStr {} parse error", rpcHeaderStr);
141+
return false;
142+
}
143+
}
144+
145+
std::string RpcServer::readArgs(const std::string& recvStr, const uint32_t headerSize, const uint32_t argsSize) {
146+
return recvStr.substr(kHeaderPrefixNum + headerSize, argsSize);
147+
}

burger/rpc/RpcProvider.h renamed to burger/rpc/RpcServer.h

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
#ifndef RPCPROVIDER_H
2-
#define RPCPROVIDER_H
1+
#ifndef RpcServer_H
2+
#define RpcServer_H
33

44
#include <google/protobuf/service.h>
55
#include <unordered_map>
@@ -13,14 +13,20 @@ namespace burger {
1313
namespace rpc {
1414

1515
// 框架提供的专门服务发布rpc服务端网络对象类
16-
class RpcProvider {
16+
class RpcServer {
1717
public:
1818
// 这里是框架提供给外部使用的,可以发布rpc方法的函数接口
19-
void NotifyService(google::protobuf::Service *service);
19+
void NotifyService(::google::protobuf::Service *service);
2020
void Run(); // 启动rpc服务接点,开始提供rpc远程网络调用服务
2121
private:
2222
void connHandler(const net::CoTcpConnection::ptr& conn);
23-
void sendRpcResonse(const net::CoTcpConnection::ptr& conn, google::protobuf::Message*);
23+
void sendRpcResonse(const net::CoTcpConnection::ptr& conn, google::protobuf::Message *);
24+
25+
std::string readHeader(const std::string& recvStr, uint32_t& headerSize);
26+
bool deserializeHeader(const std::string& rpcHeaderStr, std::string& serviceName,
27+
std::string& methodName, uint32_t& argsSize); // 反序列化头部数据,得到rpc请求的详细信息
28+
std::string readArgs(const std::string& recvStr, const uint32_t headerSize, const uint32_t argsSize);
29+
2430
private:
2531
net::Scheduler sched_;
2632
struct ServiceInfo {
@@ -37,4 +43,4 @@ class RpcProvider {
3743

3844

3945

40-
#endif // RPCPROVIDER_H
46+
#endif // RpcServer_H

burger/rpc/example/callee/friendService.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#include <iostream>
22
#include <string>
33
#include <vector>
4-
#include "../friend.pb.h" // 如何优雅的不要相对路径
5-
#include "burger/rpc/RpcProvider.h"
4+
#include "friend.pb.h" // 如何优雅的不要相对路径
5+
#include "burger/rpc/RpcServer.h"
66
#include "burger/base/Log.h"
77

88
using namespace burger;
@@ -38,7 +38,7 @@ class FriendService : public burgerRpc::FriendServiceRpc {
3838

3939
int main(int argc, char **argv) {
4040
LOGGER(); LOG_LEVEL_INFO;
41-
RpcProvider provider;
41+
RpcServer provider;
4242
provider.NotifyService(new FriendService());
4343
provider.Run();
4444
return 0;

burger/rpc/example/callee/userService.cc

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
#include <iostream>
22
#include <string>
3-
#include "../user.pb.h"
4-
#include "burger/rpc/RpcProvider.h"
3+
#include "user.pb.h"
4+
#include "burger/rpc/RpcServer.h"
55
#include "burger/base/Log.h"
66

77
using namespace burger;
88
using namespace burger::rpc;
99

10-
// UserService 原来是一个本地服务,提供了两个进程内的本地方法,Login 和GetFriendLists
11-
// 如何发布
12-
class UserService : public burgerRpc::UserServiceRpc { // 使用在rpc服务发布端(rpc服务发布者)
10+
// 使用在rpc服务发布端(rpc服务发布者)
11+
class UserService : public burgerRpc::UserServiceRpc {
1312
public:
1413
bool Login(std::string& name, std::string& pwd) {
1514
std::cout << "Doing local service : Login" << std::endl;
@@ -22,11 +21,7 @@ class UserService : public burgerRpc::UserServiceRpc { // 使用在rpc服务发
2221
std::cout << "id: " << id << " name: " << name << " pwd: " << pwd << std::endl;
2322
return true;
2423
}
25-
/*
26-
先写proto,定义好如何收发(service)的格式(是什么函数名,参数是什么字段,返回什么)
27-
1. Caller --> Login(LoginRequest) 序列化 --> Burger --> callee
28-
2. calee --> Login(LoginRequest) --> 交到下面重写的Login方法上
29-
*/
24+
3025
// 重写基类UserService 的虚函数, 下面这些方法可都是框架直接调用的
3126
// 这个Login是框架帮我们调用的
3227
void Login(::google::protobuf::RpcController* controller,
@@ -70,8 +65,9 @@ class UserService : public burgerRpc::UserServiceRpc { // 使用在rpc服务发
7065
int main(int argc, char **argv) {
7166
LOGGER(); LOG_LEVEL_INFO;
7267
// provider是一个rpc网络服务对象,把UserService对象发布到rpc结点上
73-
RpcProvider provider;
74-
provider.NotifyService(new UserService());
68+
RpcServer provider;
69+
UserService userService;
70+
provider.NotifyService(&userService);
7571
// 可以多次
7672
// provider.NotifyService(new ProductService);
7773
// 启动一个rpc服务发布节点, Run()以后,进程进入阻塞状态,等待远程的rpc调用请求

burger/rpc/example/caller/callFriendService.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <iostream>
2-
#include "../friend.pb.h"
2+
#include "friend.pb.h"
33
#include "burger/rpc/RpcChannel.h"
44
#include "burger/rpc/RpcController.h"
55
#include "burger/base/Log.h"

burger/rpc/example/caller/callUserService.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#include <iostream>
2-
#include "../user.pb.h"
2+
#include "user.pb.h"
33
#include "burger/rpc/RpcChannel.h"
44
#include "burger/base/Log.h"
55
using namespace burger;

burger/rpc/example/friend.proto renamed to burger/rpc/example/proto/friend.proto

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ message GetFriendListResponse {
1818
repeated bytes friends = 2;
1919
}
2020

21-
// 好友模块
2221
service FriendServiceRpc {
2322
rpc GetFriendList(GetFriendListRequest) returns(GetFriendListResponse);
2423
}

burger/rpc/example/user.proto renamed to burger/rpc/example/proto/user.proto

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,7 @@ message RegisterResponse {
2929
bool success = 2;
3030
}
3131

32-
// 最重要的就是 函数名 函数参数 返回 三个部分
3332
service UserServiceRpc {
34-
// 不一定和函数名相等,但是最好对应起来
3533
rpc Login(LoginRequest) returns(LoginResponse);
3634
rpc Register(RegisterRequest) returns(RegisterResponse);
3735
}

burger/rpc/example/readme.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

0 commit comments

Comments
 (0)