我的感受序列化简单来讲就是按必定规则组包。反序列化就是按组包时的规则来接包。正常来讲。序列化不会很难。不会很复杂。由于过于复杂的序列化协议会致使较长的解析时间,这可能会使得序列化和反序列化阶段成为整个系统的瓶颈。就像压缩文件、解压文件,会占用大量cpu时间。php
说序列化以前先说下平台给序列化分配的buf的空间大小前端
oCntlInfo.setOperatorUin(10458); oCntlInfo.setOperatorKey("abcde"); oCntlInfo.setRouteKey(1234); std::string source = "aaaaa"; std::string inReserve; std::string errmsg; std::string outStr; std::string machineKey; for(int i =0;i<500*1024;i++) { machineKey.append("a"); } AoActionInfo oActionInfo; oActionInfo.SetDisShopId(1111); oActionInfo.SetDistributorId(2222); uint32_t dwResult = Stub4App.AddActionSupplier( oCntlInfo, machineKey, source, 1, 1, oActionInfo, inReserve, errmsg, outStr); if(dwResult == 0) { std::cout << "Invoke OK!" << std::endl; std::cout << "Invoke OK!" << std::endl; }
客户端直接调用函数接口。到服务端请求结果c++
函数的入参都是咱们须要序列化的内容。注意这里是rpc调用的一个关键点。编程
a) 先看下咱们的thritf服务器
若是下图。发现咱们的函数入参也是打上了tag标志的。做用跟咱们在结构体中打tag标志是同样的。为了标识一个字段的含义。session
序列化的时候把这些tag序列化进去。 而后反序列化的时候靠这些tag来解析多线程
b ) 先把图贴出来。按着图来说更清晰些app
CByteStream(
char
* pStreamBuf = NULL, uint32_t nBufLen = 0,
bool
bStore=
true
,
bool
bRealWrite =
true
);
1)int32_t* pLen = (int32_t*)bs.getRawBufCur(); 2)bs << 0; 3)int32_t iLen=bs.getWrittenLength(); 4)Serialize_w(bs); 5)*pLen = bs.getWrittenLength() - iLen;
f)最后对整个_Cao_action_AddActionSupplier_Req写了两个字节的包尾函数
其实咱们能够看到咱们的这种序列化,很整齐。很规则。比较紧凑。可是并不节省空间。这个里面有不少数据能够压缩的。可是压缩带来一个问题就是解压的时候很消耗cpu的。跟个人业务场景不服和。也不必。ui
其实知道了数据是怎么写入的 解析起来就很容易了。其实这种序列化就是两边约定规则。知道规则之后就能够解析了
解析的具体步骤就不详细说了。这里说下解析的时候几个特殊的地方
咱们的这一套就是远程调用rpc服务。经过咱们的序列化。
其实就能了解所谓的RPC服务是什么样的。
说白了,远程调用就是将对象名、函数名、参数等传递给远程服务器,服务器将处理结果返回给客户端。
为了能解析出这些信息。在入参的时候作上标识(这里是打tag).
谷歌的protobuf也用过。跟thrift其实差很少可是序列化和反序列的话的具体实现是有些不一样的。
谷歌的protobuf更节省空间
之前具体看过序列化的源码。以为序列化反序列化以及rpc很神秘。如今看了源码才发现确实写的确实好,
可是没那么神秘里。其实就是按必定规则组包。因此仍是要多看源码啊。
咱们用的thrift就是 facebook的thrift。可是改了些东西。大致是同样的。