前段时间,项目内有个需求,需要由A进程向B进程发起业务请求(比如扣钱),由于扣钱是一个通用性的常规操作,势必需要封装一个通用性的接口以供不同的业务来调用。但是,考虑到不同的扣钱业务,需要的参数肯定都是不同的,如何设计一个通用的通信消息呢?
有一种最简单、暴力的方法就是不同的业务走单独的消息,这样子看上去最省力,但是实际是增加了业务的复杂性,每个新的业务逻辑就需要单独写个消息,单独做一套跨进程的处理,其实,有点劳民伤财了。
最后,采用的是union结构来设计消息结构,不同的业务结构共用一个union,union内的所有结构其实是共用一块内存的,如此一来,所有扣钱的业务都可以走一条消息来完成,不同的业务需求只需要在union里面新增自己业务需要的结构体即可。由于只走一条消息,通用的扣钱接口在A进程实现,不同的业务在A上调用该接口即可,后续跨进程扣钱的逻辑就不必再写一遍。
设计的消息结构如下:
#define MAX_DESC_LENGTH 1024
// 消息基类
struct Null_Cmd
{
// 消息类型
unsigned int msgtype = 0;
// 消息ID号
unsigned int msgid = 0;
};
// 扣钱消息
struct SubBalance : public Null_Cmd
{
SubBalance()
{
msgtype = 0;
msgid = 0;
}
// 扣钱的公共数据段
unsigned int subvalue = 0; // 扣钱金额
char desc[MAX_DESC_LENGTH] = { 0 }; // 扣钱原因
// 不同的扣钱业务的参数
union SubParam
{
// 商城购买东西
struct MARKET_BUY_GOODS
{
unsigned int marketid = 0; // 商城id
unsigned int itemid = 0; // 购买的物品项id
unsigned int num = 0; // 购买的数量
};
// 兑换游戏币
struct EXCHANGE_GAME_MONEY
{
unsigned int targettype = 0; // 兑换货币的类型
unsigned int targetvalue = 0; // 兑换货币的数量
};
// ...等等不同业务写不同的结构体
};
};