New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encode and Decode Delimited #531

Closed
usmantahirr opened this Issue Dec 9, 2016 · 9 comments

Comments

Projects
None yet
2 participants
@usmantahirr

usmantahirr commented Dec 9, 2016

I am trying to encode/decode message using encodeDelimited and decodeDelimited functions.

I want to read header message and then decide which message to decode it. and same goes for encoding, I only want to send encode and send the message which I client needs. for example, if I am invoking a command with single param, I send only single param, and I decide it using my header. I need to use encodeDelimited to encode header and message with it so that my client can see which command I've sent and can read accordingly.

same goes for Javascript side as well. if the client sends me some encoded message, I need to decode it accordingly.

for reference, I've posted by Protobuf file here.

syntax = "proto2";

//Commands Structs
message header {
    required uint32 commandType = 1;
    required uint32 commandID = 2;
}

message singleParam {
    required uint32 parameter = 1;
}

//Response structs
message responseHeader {
    required uint32 responseType = 1;
    required uint32 responseID = 2;
}

message state {
    required uint32 ambientTemperature = 1;
    required uint32 current = 2;
    required uint32 horizontalAirFlowDirection = 3;
    required uint32 connected = 4;
    required uint32 power = 5;
    required uint32 standby = 6;
    required uint32 temprature = 7;
    required uint32 thermostatFanMode = 8;
    required uint32 thermostatMode = 9;
    required uint32 verticalAirFlowDirection = 10;
    required uint32 voltage = 11;
}

//Common Structs
message setMode{
    required uint32 thermostatMode = 1;
    required uint32 thermostatSetpoint = 2;
    required uint32 thermostatFanMode = 3;
}

message noParam {}

and this is my javascript code:

  const header = root.lookup('header');
  const singleParam = root.lookup('singleParam');

  const commandType = header.lookup('commandType').name;
  const commandID   = header.lookup('commandID').name;

  const parameter = singleParam.lookup('parameter').name;

  let out = {};
  out[commandType] = 1;
  out[commandID] = 1;

  let param = {};
  param[parameter]= '100';

  // this is encoding process. here I am encoding it to send it to Device via MQTT.
  const buffer = new protobuf.BufferWriter();

  let message = header.create(out);
  let message2 = singleParam.create(param);

  header.encodeDelimited(message, buffer);
  
  singleParam.encodeDelimited(message2, buffer);
  const output = buffer.finish();

  // here I am trying to decode same thing but its giving false output.
  header.decodeDelimited(output)
  singleParam.decodeDelimited(output)

and on decoding I am getting same error again and again. ie. invalid wire type: 4

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Dec 9, 2016

Try:

  var reader = new protobuf.BufferReader(output);
  // here I am trying to decode same thing but its giving false output.
  header.decodeDelimited(reader)
  singleParam.decodeDelimited(reader)

When using 6.1.0, this is recommended instead:

  var reader = protobuf.Reader.create(output);
@usmantahirr

This comment has been minimized.

usmantahirr commented Dec 9, 2016

am I encoding right? is this the right way to encodeDelimited?

Plus, I tried this and It didn't work, still getting the same error. Nothing changed. :(

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Dec 9, 2016

With 6.1.0, that's how I'd write it:

  const header = root.lookup('header');
  const singleParam = root.lookup('singleParam');

  const writer = protobuf.Writer.create(); // or: new protobuf.BufferWriter();

  header.encodeDelimited({
   commandType: 1,
   commandID: 1
  }, writer);

  singleParam.encodeDelimited({
    parameter: 100 // not a string
  }, writer);

  const buffer = writer.finish();
  
  const reader = protobuf.Reader.create(buffer); // or: new protobuf.BufferReader(buffer);

  let myHeader = header.decodeDelimited(reader);

  let myParam = singleParam.decodeDelimited(reader);

Note: BufferWriter is for node, Writer is for browsers (but also works on node). Writer.create takes care of this - pre-6.1.0 this functionality required calling the Writer constructor as a function, though.

@usmantahirr

This comment has been minimized.

usmantahirr commented Dec 9, 2016

// This isnt working
const writer = protobuf.Writer.create();
// But this one is working fine.
const writer = new protobuf.Writer();

still getting error invalid wire type: 4 while decoding

@usmantahirr

This comment has been minimized.

usmantahirr commented Dec 9, 2016

I think there's something wrong with encoding. I am using Protobuf's C lib in Arduino, and its returning me this bytestream

  buffer[0] = 4;
  buffer[1] = 8;
  buffer[2] = 1;
  buffer[3] = 16;
  buffer[4] = 1;
  buffer[5] = 2;
  buffer[6] = 8;
  buffer[7] = 100;

This decodes correctly using method above.

but when I encode from above method, I get this

 buffer[0] = 7;
  buffer[1] = 4;
  buffer[2] = 8;
  buffer[3] = 1;
  buffer[4] = 16;
  buffer[5] = 1;
  buffer[6] = 8;
  buffer[7] = 100;
@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Dec 9, 2016

-	7	// length of 7? (that's wrong)
4	4	// length of 4
8	8	// id 1, wireType 0 (varint)
1	1	// number 1
16	16	// id 2, wireType 0 (varint)
1	1	// number 1
2	-	// length 2 (missing is wrong)
8	8	// id 1, wireType 0 (varint)
100	100	// number 100

dcodeIO added a commit that referenced this issue Dec 9, 2016

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Dec 9, 2016

Please try again with the current master version.

dcodeIO added a commit that referenced this issue Dec 9, 2016

@dcodeIO dcodeIO removed the question label Dec 9, 2016

@usmantahirr

This comment has been minimized.

usmantahirr commented Dec 10, 2016

Working perfectly fine now. Thanks 👍

But how do I update npm now :P
I don't want to clone master branch each time.

@dcodeIO

This comment has been minimized.

Owner

dcodeIO commented Dec 11, 2016

6.1.0 is now also on npm!

@dcodeIO dcodeIO closed this Dec 11, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment