vlambda博客
学习文章列表

使用thrift进行序列化与反序列化

在消息传输过程中,可以使用thrift工具对数据进行序列化和反序列化处理,然后再放在系统间进行传输,可以大大提升通信的效率。


thrift版本:0.11.0

编写thrift文件

namespace java Hanfire
struct Message {1: i8 id,2: string data,}

python

from helloWorld.ttypes import *from thrift import TSerialization
msg = Message()msg.id = 1msg.data = "hello hanfire"
tmp = TSerialization.serialize(msg)
msg2 = Message()TSerialization.deserialize(msg2, tmp)
print(msg2) # Message(id=1, data='hello hanfire')

java

Message msg = new Message();TSerializer serializer = new TSerializer();byte[] bytes = serializer.serialize(msg);System.out.println(Arrays.toString(bytes));
Message msg2 = new Message();TDeserializer deserializer = new TDeserializer();deserializer.deserialize(msg2, bytes);

c++

没有现成的序列化和反序列化工具,需要自己实现

#include <thrift/protocol/TBinaryProtocol.h>#include <thrift/transport/TTransportUtils.h>using namespace apache::thrift;using namespace apache::thrift::transport;using namespace apache::thrift::protocol;
template <typename X> std::string Serialize(const X &ts) {  stdcxx::shared_ptr<TMemoryBuffer> membuffer(new TMemoryBuffer());  stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(membuffer));  ts.write(protocol.get());  return membuffer->getBufferAsString();}
template <typename X> void Deserialize(const std::string &buff, X *ts) {  uint8_t *p = (uint8_t *)(buff.data());  uint32_t size = buff.size();   stdcxx::shared_ptr<TMemoryBuffer> membuffer(new TMemoryBuffer(p, size)); stdcxx::shared_ptr<TProtocol> protocol(new TBinaryProtocol(membuffer));  ts.read(protocol.get());}

一般情况下使用二进制类型的传输协议(提高传输效率,多数用于内部系统之间的通信传输),还可以使用基于文本类型的协议(json),json,xml作为通用网络数据传输协议,可以实现外部系统调用。

  • TBinaryProtocol- 二进制编码格式进行数据传输(默认)

  • TCompactProtocol- 高效率,密集的二进制编码格式进行数据传输(了解protocol buffer内部编码实现的话,就不足为奇了)

  • TJSONProtocol - 使用JSON的数据编码协议进行数据传输。

  • TSimpleJSONProtocol- 只提供JSON写的协议,通过脚本语言解析


果换成其他格式的协议,只需要更新protocol的类型就行。

看看python的序列化及反序列化的源码实现就明白了。

from .protocol import TBinaryProtocolfrom .transport import TTransport
def serialize(thrift_object, protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): transport = TTransport.TMemoryBuffer() protocol = protocol_factory.getProtocol(transport) thrift_object.write(protocol) return transport.getvalue()
def deserialize(base, buf, protocol_factory=TBinaryProtocol.TBinaryProtocolFactory()): transport = TTransport.TMemoryBuffer(buf) protocol = protocol_factory.getProtocol(transport) base.read(protocol) return base