Gaea源码阅读(五):C客户端

Gaea不仅有Java客户端,还提供了C语言和.NET实现,其中C客户端的序列化/反序列化为C语言重写。文章重点介绍了Debug/conf/struct.conf文件的生成,它由FileScan工具根据src/structScan目录下的源代码生成。FileScan用于扫描结构体定义,结果保存在structMap中,struct.conf文件记录每个结构体信息。客户端执行流程包括配置解析、请求构造及序列化操作。

除了Java客户端外,Gaea还提供了C语言和.NET实现。


基本都是相同的,只是序列化/反序列化用C语言重新实现了。你可能会注意到一个特别的文件:Debug/conf/struct.conf ,这个文件曾经让我很迷惑。


实际上,gaea还提供了一个编译过的可执行文件FileScan,源代码位于src/structScan目录下,入口main被重命名为了mainY。


struct.conf就是通过FileScan按如下命令生成的,

FileScan -f 定义实体类的文件


FileScan.structScan扫描结构体定义文件,可识别struct、typedef定义。

结果保存到std::map<std::string, scanStructInfo*> structMap;

然后writeConfig保存到struct.conf中


产生的struct.conf每行一个结构体

ExceptionProtocol,-1300746967,32,0;fromIP,char,-139515017,16,1;errorCode,int,824862661,0,0;ErrorMsg,char,931829677,24,1;toIP,char,1461299386,8,1;

 

typedef struct {
	int errorCode;
	char *toIP;
	char *fromIP;
	char *ErrorMsg;
} ExceptionProtocol;

一行一个实体,第一个分号之4个字段,后面的都是5个字段。


读取格式:

fieldname

typeId

//非首跳过

offset

isPointer


Client执行流程

//GeeaClientTest

int main(int argc, char *argv[]) {
	GaeaClientTest *ha = new GaeaClientTest();
	std::string configFile="/项目路径/c-gaea/Debug/conf/gaea.config";
	std::string s1 = "//项目路径/c-gaea/Debug/conf/struct.conf";
	std::string logFile = "//项目路径/c-gaea/Debug/conf/gaea.log"
	gaea::GaeaClientConfig().init(configFile,s1,logFile);
	ha->NewsServiceTest();}
//首先加载配置以及实体类

gaea.config通过tinyxpath解析,然后注册实体类。

//structHelper.registerStruct
		sfi->typeId = atoi(c);
		key = malloc(sizeof(int));
		*key = sfi->typeId;

		//扫描字段
		while{
			byteArrayPutData(value, sfi, sfiSize);
			++cursor;
		}

		//注册结构体id -> 结构体信息
		objc_hash_add(&structInfoMap, key, value);


//客户端调用

ps->invoke("getNewsByCateID",NULL,0);


//构造RequestProtocol

//serviceProxy.
	RequestProtocol requestProtocol;
	requestProtocol.lookup = lookup;
	requestProtocol.methodName = methodName;
	requestProtocol.paraList = paraList;
	std::string sdpEntityType = "RequestProtocol";

	Protocol sendP(sid, config->getServiceId(), Request, UnCompress, GAEABinary, Java, &requestProtocol, sdpEntityType.c_str());

receiveP = server->request(sendP);

//server.request

         char*data = p.getBytes(dataLen);


//Protocol.getBytes

         char*sdpData = Serialize(sdpEntityType, sdpEntity, &serDataLen);


//序列化Protocol

	int typeId = GetTypeId(type);
	serializerInfo info = { outArray:&retArray, hashcode:1000, refObjArray:&refObjArray };

	serializer sr = getSerializer(typeId, obj); //函数指针
	sr(typeId, &info, obj); //提取typeId类型的obj对象信息,存到info中

//默认getSerilizer返回structSeralizer

	array *structInfo = objc_hash_value_for_key(structInfoMap, &typeId);

	for (i = 1; i < fieldLen; ++i) {
		newObj = obj + sfi->offset;
		if (sfi->isPointe == 1) {
			if (sfi->typeId == SERIALIZE_VOID_N) {
				t = *(int*) (obj + sfi->offset + sizeof(void*));
				sr = getSerializer(t, *(void**) newObj);
			} else {
				t = sfi->typeId;
				sr = getSerializer(sfi->typeId, *(void**) newObj);
			}
			if (sr != nullSerializer && sr != enumSerializer) {
				byteArrayPutData(info->outArray, &t, 4);
			}
			sr(t, info, *(void**) newObj);
		} else {
			sr = getSerializer(sfi->typeId, newObj);
			if (sr != nullSerializer && sr != enumSerializer) {
				byteArrayPutData(info->outArray, &sfi->typeId, 4);
			}
			sr(sfi->typeId, info, newObj);
		}
		++sfi;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值