在nodejs中使用Apache Thrift进行序列化 - 反序列化

时间:2012-11-09 15:01:42

标签: node.js serialization deserialization thrift

我正在研究Node.js应用程序,我需要序列化和反序列化.thrift文件中定义的结构的实例,如下所示:

 struct Notification {
   1: string subject,
   2: string message
 }

根据http://www.gettingcirrius.com/2011/03/rabbitmq-with-thrift-serialization.html的教程

,现在这在Java中很容易实现
    Notification notification = new Notification();
    TDeserializer deserializer = new TDeserializer();
    deserializer.deserialize(notification, serializedNotification);
    System.out.println("Received "+ notification.toString());

但我无法找到如何使用Thrift的nodejs库完成这项工作。有人可以帮忙吗?

3 个答案:

答案 0 :(得分:7)

好的,在浪费了大量时间进行研究并尝试不同的解决方案之后,我终于找到了自己问题的答案:

//SERIALIZATION:
var buffer = new Buffer(notification);
var transport = new thrift.TFramedTransport(buffer);
var binaryProt = new thrift.TBinaryProtocol(transport);
notification.write(binaryProt);

其中notification是我希望序列化的对象。此时,可以在transport.outBuffers字段中找到字节数组:     var byteArray = transport.outBuffers;

反序列化:

var tTransport = new thrift.TFramedTransport(byteArray);
var tProtocol = new thrift.TBinaryProtocol(tTransport);
var receivedNotif = new notification_type.Notification();
receivedNotif.read(tProtocol);

假设已经从nodejs库为thrift添加了以下行到index.js文件中:

exports.TFramedTransport = require('./transport').TFramedTransport;
exports.TBufferedTransport = require('./transport').TBufferedTransport;
exports.TBinaryProtocol = require('./protocol').TBinaryProtocol;

答案 1 :(得分:0)

这是我在浏览器中运行的TypeScript版本。 npm install buffer在使用之前。

如果您删除import { Buffer },它将在节点上正常工作。

/*
 Thrift serializer for browser and node.js

 Author: Hirano Satoshi

 Usage:
    let byteArray = thriftSerialize(thriftObj);
    let thriftObj2 = thriftDeserialize(byteArray, new ThriftClass())
    let mayBeTrue = byteArrayCompare(byteArray, thriftSerialize(thriftObj2))
 */

import { TBufferedTransport, TFramedTransport, TJSONProtocol, TBinaryProtocol } from 'thrift';
import { Buffer } from 'buffer';

export function thriftSerialize(thriftObj: any): Buffer {
    let transport = new TBufferedTransport(null);
    let protocol = new TBinaryProtocol(transport);
    thriftObj.write(protocol);

    // copy array of array into byteArray
    let source = transport.outBuffers;
    var byteArrayLen = 0;
    for (var i = 0, len = source.length; i < len; i++)
        byteArrayLen += source[i].length;
    let byteArray = new Buffer(byteArrayLen);
    for (var i = 0, len = source.length, pos = 0; i < len; i++) {
        let chunk = source[i];
        chunk.copy(byteArray, pos);
        pos += chunk.length;
    }
    return byteArray;
}

export function thriftDeserialize(byteArray: Buffer, thriftObj: any): any {
    let transport = new TBufferedTransport(byteArray);
    let callback = (transport_with_data) => {
        var proto = new TBinaryProtocol(transport_with_data);
        //    var proto = new TJSONProtocol(transport);
        thriftObj.read(proto);
    }
    // var buf = new Buffer(byteArray);

    TBufferedTransport.receiver(callback)(byteArray);
    return thriftObj;
}

export function byteArrayCompare(array1, array2): boolean {
    if (!array1 || !array2)
        return false;
    let val = array1.length === array2.length && array1.every((value, index) => value === array2[index])
    return val;
}

答案 2 :(得分:0)

以某种方式我在以下位置找不到字节数组:

transport.outBuffers

我需要执行以下操作:

         var transport = new Thrift.TFramedTransport(null, function(bytes){
            dataWrapper.out = bytes;
            cb(dataWrapper)
        })


        var binaryProt = new Thrift.TCompactProtocol(transport);
        notification.write(binaryProt) ;
        transport.flush() ; //important without the flush the transport callback will not be invoked