1

我正在使用 protobufs 来序列化我的数据。到目前为止,我在服务器上序列化了我的数据(节点 restify)发送它,接收它(请求由 XMLHttpRequest 发出)并在客户端上序列化它。

现在我想使用压缩来减少传输的文件大小。我尝试使用使用 zlib 的库pako

在我用来比较 protobuf 和 zipping 性能与 json 的基本脚本中,我以这种方式使用它,没有问题

var buffer = proto.encode(data,'MyType'); // Own library on top of protobufs
var output = pako.deflate(buffer);
var unpacked = pako.inflate(output);
var decoded = proto.decode(buffer,'MyType');

但是,如果我尝试在客户端-服务器模型中执行此操作,我将无法使其正常工作。

服务器:

server.get('/data', function (req, res) {
   const data = getMyData();
   const buffer = proto.encode(data, 'MyType');
   res.setHeader('content-type', 'application/octet-stream;');
   res.setHeader('Content-Encoding', 'gzip;');
   return res.send(200,buffer);
});

我自己的proto库将 protobuf 中的数据序列化,然后将其放气:

...
let buffer = type.encode(message).finish();
buffer = pako.deflate(buffer);
return buffer;

请求如下所示:

public getData(){
    return new Promise((resolve,reject) => {
        const request = new XMLHttpRequest();
        request.open("GET", this.url, true);
        request.responseType = "arraybuffer";
        request.onload = function(evt) {
            const arr = new Uint8Array(request.response);
            const payload = proto.decode(request.response ,'MyType')
            resolve(payload);
        };
        request.send();
    });
}

proto.decode 方法首先膨胀缓冲区buffer = pako.inflate(buffer);,然后从 Protobuf 反序列化它。

如果发出请求,我会收到以下错误:pako 的 inflate 方法返回“未捕获的错误标头检查” :

function inflate(input, options) {
  var inflator = new Inflate(options);

  inflator.push(input, true);

  // That will never happens, if you don't cheat with options :)
  if (inflator.err) { throw inflator.msg || msg[inflator.err]; }

  return inflator.result;
}

我还查看了 Postman 中的请求,发现以下内容:放气的响应如下所示:120,156,60,221,119,64,21,237,119,39,240,247,246,242,10,49,191,244,178,73,54,157并且长度为 378564

没有放气的相同请求(protobuf)看起来像这样 �:�: (� 0�8@H (� 0�8@H � (�0�8@�H,长度为 272613。

我假设我在服务器端做错了什么,因为膨胀的请求比不使用压缩的请求大。它是内容类型的标题吗?我没主意了。

4

0 回答 0