【问题标题】:Writing/reading protocol buffers写/读协议缓冲区
【发布时间】:2017-02-16 16:37:26
【问题描述】:

为了通过线路将复杂的 JSON/JavaScript 对象发送到 C++ 二进制文件,我使用的是协议缓冲区。这些天有对 Node.js 的原生 protobuf 支持,所以我没有使用任何其他绑定。

// Set maximum execution time of binary to equal the
// remainder of processing time, minus a second to allow
// for parsing.
var timeLimit = context.getRemainingTimeInMillis() - 1000;

// Check if meta parameters are given in the request.
// Assign default values if they are not.
var model = new protocols.Model();

// Sort the resolutions.
function descending(a, b) {
    if (a.width > b.width) {
        return -1;
    } else if (a.width < b.width) {
        return 1;
    }
    return 0;
}

// Construct image objects.
var images = request.images.map(function(image) {
    // Perform the sort.
    image.resolutions.sort(descending);

    // Create an image protobuffer.
    var imageProto = new protocols.Model.Image();

    // Assign the original's resolution to the image.
    imageProto.setWidth(image.resolutions[0].width);
    imageProto.setHeight(image.resolutions[0].height);

    // Return the result.
    return imageProto;
});

// Construct flag enumeration references.
var flags = request.flags.map(function(flag) {
    return protocols.Model.Flag[flag];
});

// Assign request properties to protobuf.
model.setImagesList     (images                                                     );
model.setFlagsList      (flags                                                      );
model.setMinNoOfPages   (request.minNoOfPages   ? request.minNoOfPages  : 1         );
model.setMaxNoOfPages   (request.maxNoOfPages   ? request.maxNoOfPages  : 1         );
model.setMaxPerPage     (request.maxPerPage     ? request.maxPerPage    : 5         );
model.setPageWidth      (request.pageWidth      ? request.pageWidth     : 3508      );
model.setPageHeight     (request.pageHeight     ? request.pageHeight    : 2480      );
model.setTimeLimit      (request.timeLimit      ? request.timeLimit     : timeLimit );
model.setBorderWidth    (request.borderWidth    ? request.borderWidth   : 0         );
model.setMinDim         (request.minDim         ? request.minDim        : 0         );

// This is where things go wrong.
var serialized = model.serializeBinary();
fs.writeFileSync('model.pb', serialized);
var read = fs.readFileSync('model.pb'),
    model2 = protocols.Model.deserializeBinary(read);

console.log(model.toObject());
console.log(model2.toObject());

上面是我坚持的一段代码。我设法编译了一个 protobuf 消息:

syntax = "proto3";

package layout;

message Model {

    enum Flag {
        FILL_PAGE = 0;
        BORDERS = 1;
    }

    message Image {
        int32 width = 1;
        int32 height = 2;
    }

    repeated Flag flags = 1;
    repeated Image images = 2;

    string avoid_layout = 3;
    int32 min_no_of_pages = 4;
    int32 max_no_of_pages = 5;
    int32 max_per_page = 6;
    int32 page_width = 7;
    int32 page_height = 8;
    int32 time_limit = 9;
    int32 border_width = 10;
    int32 min_dim = 11;
}

但是,关于 JavaScript 对 protobuf 的支持的文档很少 (https://developers.google.com/protocol-buffers/docs/reference/javascript-generated#message),我不知道如何将消息读取到文件中,然后再次读取它们。有人可以向我解释如何做到这一点吗?

我想解决方案是我代码的最后几行的一些变化,但目前我收到了这个错误:

AssertionError: Failure: Type not convertible to Uint8Array.

【问题讨论】:

  • 是哪个代码行?我猜model2 = protocols.Model.deserializeBinary(read)
  • 是的,该行导致错误。
  • read instanceof Uint8Array 的结果是什么?如果为 false,您使用的是哪个版本的 node
  • 计算结果为true

标签: javascript protocol-buffers


【解决方案1】:

您可能正在目睹节点Buffer 未被识别为Uint8Array 的一些模糊案例。我找到了relevant issue report。所以尝试使用

强制类型
protocols.Model.deserializeBinary(new Uint8Array(read));

replacing the constructor。该建议与您的建议特别相似 - 它也在读取二进制文件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-18
    • 2021-12-19
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多