rpc_service
简介
提供RPC服务
一个RPC服务集群拥有一个中心节点(master),其他节点都是普通节点(slave);中心节点同时也具有一个普通节点的功能。
集群中的每个节点都必须有一个唯一的id(由rpc服务的ip和端口组成一个唯一的id)。
中心节点区别于普通节点的地方是:中心节点存储/共享 集群里各普通节点的信息。
一个普通节点只有在中心节点正确登记之后,才会被集群中的其他节点访问。
分布在各个节点上的可供RPC方式访问的资源,都具有一个RPC地址,该地址在集群内是唯一的。
格式:[id]|[catalog]|[RID]
-
id
: 节点的唯一id(特别的,当RPC地址中的id是'/'时,对应的是中心节点) -
catalog
: 资源类别;需要提供这种类别的定位函数以便定位到资源对象或者函数方法;可以通过rpc_entry设置定位函数 -
RID
: 资源在节点上的id;提供给catalog对应的定位函数用于定位资源的对象或者函数方法
例如:
-
"127.0.0.1|m|M000062134CB8003F":"127.0.0.1:5555|m|M000062134CB8003F";其中127.0.0.1是资源所在节点的id,m是资源的类别,M000062134CB8003F是资源的id
-
"/|D|abc.gs":'/'是指中心节点,'D'是指访问的资源是一个模块对象,'abc.gs'是模块文件的名称
默认支持两种资源类别:
-
D: RPC调用目标节点上的daemon模块(通过find_object定位daemon模块)
-
G: RPC调用目标节点上的全局函数
实际的应用可以参考示例项目server1中的game.mods.remote
组件接口
FRpcRelay.gs
提供RPC中继调用功能的组件
需要提供中继处理RPC请求的对象需要继承本组件
函数原型 | 函数作用 |
---|---|
void relay_post(string target, string method, ...) | 中继处理POST请求 |
mixed relay_get(string target, string method, ...) | 中继处理GET请求 |
RpcUtil.gs
RPC地址相关的一些功能函数;比如生成RPC地址、通RPC地址发起RPC调用等。
rpc_config.gs
RPC服务配置
函数原型 | 函数作用 |
---|---|
void init(map config) | 初始化配置 |
void set(string key, mixed value) | 设置配置 |
mixed get(string path, mixed default_value = nil) | 获取配置 |
mixed calc(string path, ...) | 计算配置 |
string get_mask_id() | 获取主控的服务器ID |
string get_mask_token() | 获取用于指代主控的服务器标识 |
void dump() | 调试接口 - 输出配置信息 |
rpc_master.gs
主节点上管理所有从节点信息的模块
函数原型 | 函数作用 |
---|---|
bool add_slave(string id, map info) | 添加一个从节点 |
map get_slave_info(string id) | 获取从节点信息 |
void walk_all_slaves(function func) | 遍历所有从节点 |
map get_master_info() | 获取主节 点信息 |
rpc_service.gs
函数原型 | 函数作用 |
---|---|
bool start(map para) | 启动RPC服务 |
void stop() | 停止RPC服务 |
rpc_serviced.gs
这里实现RPC服务的主要功能
开启RPC网络服务
在中心节点登记本节点信息
向资源RPC地址发起POST/GET调用
一般情况下,没有直接必要使用本模块中的接口,应该使用rpc_util或者rpc_service中的。
函数原型 | 函数作用 |
---|---|
bool start() | 开启服务 |
void stop() | 停止服务 |
mixed remote_get(string address, string method, array args) | 向一个资源RPC地址发起GET(阻塞)调用 |
array remote_get_multi(array address_list, string method, array args) | 向一组资源RPC地址发起GET(阻塞)调用 |
void remote_post(string address, string method, array args) | 向一个资源RPC地址发起POST(非阻塞)调用 |
void remote_post_multi(array address_list, string method, array args) | 向一组资源RPC地址发起POST(非阻塞)调用 |
rpc_slave.gs
从节点访问主节点获取集群中所有节点信息的模块
函数原型 | 函数作用 |
---|---|
map fetch_master_info() | 作为从节点时,访问主节点获取主节点的完整信息 |
bool register_self() | 作为从节点时,访问主节点登记自身完整信息 |
map get_slave_info(string id) | 作为从节点,访问主节点获取从节点的完整信息 |
类
CustomRpcConfig
继承自 RpcConfig
RPC服务配置
成员变量
变量名 | 类型 | 初始值 | 须初始化 | 描述 |
---|---|---|---|---|
ip | mixed | nil | 可选 | 本节点的IP |
port | mixed | nil | 可选 | 本节点的端口 |
id | string | nil | 可选 | 本节点的ID(一般由IP/端口组成) |
master | mixed | nil | 可选 | 本节点作为从节点时连接的主节点服务器信息{ "ip" : ip, "port" : port } |
as_master | mixed | nil | 可选 | 本节点作为主节点时额外登记的一些信息{} |
as_slave | mixed | nil | 可选 | 本节点作为从节点时额外登记的一些信息{} |
port_recv_size | int | 0 | 可选 | RPC网络连接的接收缓冲区大小 |
max_send_size | int | 0 | 可选 | RPC网络连接允许发送的最大数据包长度 |
rpc_timeout | int | 0 | 可选 | 默认超时时长(单位:秒;默认为30秒) |
mask_token | string | nil | 可选 | 指代主节点的标识 |
mask_id | string | nil | 可选 | 主节点的ID |
成员方法
函数原型 | 函数作用 |
---|
样例
// 开启服务的sample
#pragma parallel
import gs.lang.*;
import gs.util.*;
import pkg.rpc_service;
void create()
{
// 启动rpc服务
// 既作为主节点又作为从节点
map para = {
// 本节点的ip和端口
"ip" : "127.0.0.1",
"port" : 7432,
// 作为从节点时 - 登记的额外信息
"as_slave" : {
},
// 作为从节点时 - 主节点的ip和端口
"master" : {
"ip" : "127.0.0.1",
"port" : 7432,
},
// 作为主节点时 - 登记的额外信息
"as_master" : {
"test" : 1,
},
// RPC网络连接的最大接收缓冲区大小
"port_recv_size" : 1024 * 512,
// RPC请求超时时长
"rpc_timeout" : 15,
// POST调用应答消息的处理协程数量
"post_coroutine_num" : 4,
};
rpc_service.start(para);
}
public int calc(...)
{
int total = 0;
for (int v : $<)
total += v;
return total;
}
public void say(string word)
{
printf("%s\n", word);
}
// 演示一下通过远程调用调用自己的方法
public void sample()
{
// 启动配置
string addr1= make_rpc_address(__FILE__, "D", "/");
mixed result = addr1.GET("calc", 1, 2, 3, 4, 5);
printf("result1=%M\n", result);
addr1.POST("say", "hello");
string addr2 = make_rpc_address(__FILE__, "D", "/");
mixed result2 = addr2.GET("calc", 11, 12, 13, 14, 15);
printf("result2=%M\n", result2);
addr2.POST("say", "world");
string addr3= make_rpc_address(__FILE__, "D", "127.0.0.1:7432");
mixed result3 = addr3.GET("calc", 1, 2, 3, 4, 5);
printf("result3=%M\n", result3);
addr1.POST("say", "hello3");
string addr4 = make_rpc_address(__FILE__, "D", "127.0.0.1:7432");
mixed result4 = addr4.GET("calc", 11, 12, 13, 14, 15);
printf("result4=%M\n", result4);
addr2.POST("say", "world4");
}