NodeJS新手如何正确使用Protobuf并创建有效Protobuf对象?
Hey there! Let's break this down step by step—no fancy jargon, just straightforward guidance to get you up and running with Protobuf in Node.js, and fix that empty ToRadio {} issue you're seeing.
First: Why your current code isn't working
That empty ToRadio {} output happens because the field you're trying to set isn't a top-level field in the ToRadio message. Let's look at the structure from your .proto file: ToRadio uses a oneof type, which means only one of its sub-fields can be set at a time. The want_config_id you're targeting actually lives inside the ConfigApp message, which is nested under ToRadio's config_app field. Protobuf ignores fields that don't exist on the target message, hence the empty object.
Quick Core Protobuf Concepts (No Fluff)
Before diving into code, let's get the basics straight so you can read .proto files without confusion:
- Message: The blueprint for your objects (think of it like a class in JS).
ToRadioandConfigAppare both messages. - oneof: A group of fields where only one can be set at once—if you set a second, the first gets cleared.
- Field Numbers: The numbers after each field (like
int32 want_config_id = 5;). Protobuf uses these instead of field names for serialization, so never change them! - Encode/Decode: Turning your JS object into binary (encode) or binary back into a JS object (decode).
Your Scenario: Correctly Use the mesh.proto File
Step 1: Make sure you have the right library
You're using protobufjs, which is perfect—just double-check it's installed:
npm install protobufjs
Step 2: Understand the ToRadio Structure
Here's the simplified critical part of the .proto you're using:
message ToRadio { oneof payload { ConfigApp config_app = 2; // Other oneof options omitted... } } message ConfigApp { uint32 want_config_id = 5; // Other ConfigApp fields omitted... }
Notice: want_config_id belongs to ConfigApp, and ConfigApp is a sub-field of ToRadio's oneof group. So you need to build the ConfigApp first, then attach it to ToRadio.
Step 3: Fix Your Code
Here's the corrected version with comments explaining each step:
const protobuf = require('protobufjs'); const util = require('util'); // 1. Load the .proto file (double-check the file path is correct!) const root = protobuf.loadSync('Meshtastic-protobufs/mesh.proto'); // 2. Look up both message types we need: ToRadio AND ConfigApp const ToRadio = root.lookupType('ToRadio'); const ConfigApp = root.lookupType('ConfigApp'); // 3. First create the ConfigApp object with your want_config_id value const configAppMessage = ConfigApp.create({ want_config_id: 12345678 }); // 4. Create the ToRadio object, attaching the ConfigApp to its config_app field const toRadioMessage = ToRadio.create({ config_app: configAppMessage }); // 5. Serialize the object to binary buffer const buffer = ToRadio.encode(toRadioMessage).finish(); // 6. Decode the buffer back to an object to verify (use depth:null to see nested fields) const decoded = ToRadio.decode(buffer); console.log(util.inspect(decoded, { depth: null }));
Run this, and you'll see the full nested object with your want_config_id value included!
Quick Pro Tips
- Validate your messages: Use the
verifymethod to catch invalid data before encoding:const validationError = ConfigApp.verify({ want_config_id: 12345678 }); if (validationError) throw new Error(validationError); - Inspect message structures: Print the message type to see all fields and their rules:
console.log(ToRadio.type); - Watch file paths: If you get "type not found" errors, use an absolute path for your
.protofile to rule out path issues.
Common Pitfalls to Avoid
- Setting nested fields directly: Never try to set
want_config_iddirectly onToRadio—Protobuf will ignore it because that field doesn't exist at the top level. - Type mismatches:
want_config_idis auint32(unsigned integer), so stick to number values (no strings) to avoid unexpected behavior. - Ignoring oneof rules: If you set multiple
oneoffields onToRadio, only the last one you set will be kept.
内容的提问来源于stack exchange,提问作者Stefan Gofferje

