除了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);
char*sdpData = Serialize(sdpEntityType, sdpEntity, &serDataLen);
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;
}