NodeJS protobuf.encode()在protobufjs包中无法正常工作

c9x0cxw0  于 2023-06-29  发布在  Node.js
关注(0)|答案(1)|浏览(153)

我用的是protobufjs这个包。
这个问题浪费了我4天的时间,我不明白为什么?verify()没有错误,所有的属性也设置好了,我确信文件和它们的导入也加载好了,有问题,在我的项目的另一边所有的使用都没有问题,但是在这一边我有这个问题
protobuf.js版本:^7.2.3

let settings = {
            port_list: {
                range: [{
                    From: 1,
                    To: 100
                }]
            },
            listen: {},
            allocation_strategy: {},
            stream_settings: {},
            receive_original_destination: {},
            sniffing_settings: {
                enabled: false
            }
        }
        let error = ReceiverSetting.verify(settings)
        let receiverSetting = ReceiverSetting.create(settings)
        console.log('error: ', error)
        const buffer = ReceiverSetting.encode(receiverSetting).finish();
        console.log('receiverSetting:', receiverSetting);
        console.log('buffer:', buffer);
        const decodedMessage = ReceiverSetting.decode(buffer);
        console.log('decodedMessage:', decodedMessage);

在日志部分:

error:  null
receiverSetting: ReceiverConfig {
  domainOverride: [],
  port_list: { range: [ [Object] ] },
  listen: {},
  allocation_strategy: {},
  stream_settings: {},
  receive_original_destination: {},
  sniffing_settings: {}
}
buffer: <Buffer 12 00>
decodedMessage: ReceiverConfig { domainOverride: [], listen: IPOrDomain {} }

原始文件:

syntax = "proto3";

package xray.app.proxyman;

import "common/net/address.proto";
import "common/net/port.proto";
import "transport/internet/config.proto";
import "common/serial/typed_message.proto";

...
...
...
message ReceiverConfig {
  xray.common.net.PortList port_list = 1;
  xray.common.net.IPOrDomain listen = 2;
  AllocationStrategy allocation_strategy = 3;
  xray.transport.internet.StreamConfig stream_settings = 4;
  bool receive_original_destination = 5;
  reserved 6;
  repeated KnownProtocols domain_override = 7 [ deprecated = true ];
  SniffingConfig sniffing_settings = 8;
}
message SniffingConfig {
  // Whether or not to enable content sniffing on an inbound connection.
  bool enabled = 1;

  // Override target destination if sniff'ed protocol is in the given list.
  // Supported values are "http", "tls", "fakedns".
  repeated string destination_override = 2;
  repeated string domains_excluded = 3;

  // Whether should only try to sniff metadata without waiting for client input.
  // Can be used to support SMTP like protocol where server send the first
  // message.
  bool metadata_only = 4;

  bool route_only = 5;
}
...
...
...
...
j13ufse2

j13ufse21#

我对protobufjs不熟悉。
不清楚您从哪里获取xray,但我使用了Xray-core并将protobuf源代码复制到我的protos目录(如下所示)。
我不得不更改一个Xray-core引用以编译树。
结构:

.
├── foo.json
├── index.js
├── node_modules
├── package.json
├── package-lock.json
├── protos
│   └── xray
│       ├── app
│       ├── common
│       ├── core
│       └── transport
└── README.md

我修改了你的proto,这样我就可以编译它了:foo.proto

syntax = "proto3";

package xray.app.proxyman;

import "xray/common/net/address.proto";
import "xray/common/net/port.proto";
import "xray/transport/internet/config.proto";
import "xray/common/serial/typed_message.proto";

message ReceiverConfig {
  xray.common.net.PortList port_list = 1;
  xray.common.net.IPOrDomain listen = 2;
//  AllocationStrategy allocation_strategy = 3;
  xray.transport.internet.StreamConfig stream_settings = 4;
  bool receive_original_destination = 5;
  reserved 6;
//  repeated KnownProtocols domain_override = 7 [ deprecated = true ];
  SniffingConfig sniffing_settings = 8;
}
message SniffingConfig {
  // Whether or not to enable content sniffing on an inbound connection.
  bool enabled = 1;

  // Override target destination if sniff'ed protocol is in the given list.
  // Supported values are "http", "tls", "fakedns".
  repeated string destination_override = 2;
  repeated string domains_excluded = 3;

  // Whether should only try to sniff metadata without waiting for client input.
  // Can be used to support SMTP like protocol where server send the first
  // message.
  bool metadata_only = 4;

  bool route_only = 5;
}

1.前缀xray引用,例如xray.common.net.PortList
1.未定义的评论消息,例如AllocationStrategy
我不清楚如何使用protobufjs指定proto_path,所以我编译为JSON模式:

./node_modules/.bin/pbjs \
--path=${PWD}/protos \
${PWD}/protos/xray/app/proxyman/foo.proto \
> foo.json

然后:
index.js

var protobuf = require("protobufjs");

protobuf.load("foo.json").then((root) => {
  console.log(root);

  const ReceiverConfig = root.lookupType("xray.app.proxyman.ReceiverConfig");

  // By introspecting foo.json schema:
  // 1. portList not port_list
  // 2. From|To initial letter uppercase
  const payload = {
            portList: {
                range: [{
                    From: 1000,
                    To: 1999,
                }],
            },
        };

  const errMsg = ReceiverConfig.verify(payload);
  if (errMsg)
    throw Error(errMsg);

  const message = ReceiverConfig.create(payload);
  console.log(`receiverSetting: ${JSON.stringify(message)}`);

  const buffer = ReceiverConfig.encode(message).finish();

  const decoded = ReceiverConfig.decode(buffer);
  console.log(`receiverSetting: ${JSON.stringify(message)}`);
}).catch((err) => {
  console.log(err);
});

产量:

receiverSetting: {"portList":{"range":[{"From":1000,"To":1999}]}}
receiverSetting: {"portList":{"range":[{"From":1000,"To":1999}]}}

相关问题