Read protobuf message from websocket connection

Hello guys,

Currently im working on loadtest for websocket, but it doesnt use usual message like JSON, but it was using protobuf message.
I was successfully to send protobuf message to server.
But when I want to read message from server and write on console using this code

     socket.on('message', function (message) {
        console.log(`Received message: ${message}`);
      });

that given me like this

Am I missed something here?

nb: i follow the steps in this repo GitHub - sparrowjack/k6_protobuff_demo: a demo implement the k6[https://k6.io] load test tool to send protobuf message to server

Hi there!

GitHub - sparrowjack/k6_protobuff_demo: a demo implement the k6[https://k6.io] load test tool

That’s an interesting project, thanks for sharing.

The problem is that you’re logging the stringified binary message, which will only output garbage.

I’m not familiar with the protobuf JS implementation, but have you tried deserializing the received message?

According to the API docs and that demo repo, I would try this:

socket.on('message', function (message) {
  let msg = new proto.Message();
  let dMsg = msg.deserializeBinary(message);
  // read fields from dMsg
});

Unfortunately, this is a bit hacky right now, since the WebSocket implementation in k6 only supports string messages. This should be easier now that ArrayBuffer is natively supported in goja (the JS VM k6 uses), and we’ll consider addressing this use case in upcoming versions.

seems like it doesnt work either bro @imiric :cry:

i think if i want to read the incoming message, i have to make kind of message mapping using the related .proto file
i read it from here GitHub - protobufjs/protobuf.js: Protocol Buffers for JavaScript (& TypeScript).

is k6 support to read typescript code?

What doesn’t work specifically? Do you get any errors?

That page mentions that TypeScript is optional and you can access fields in plain JS with bracket notation. That said, no, k6 doesn’t read TypeScript directly, but you could use a bundler like Webpack to pre-transform the TS to JS and load that in k6. See the template-es6 project for a start.

when i was using this method, it returned error like this

TypeError: Object has no member 'deserializeBinary'

even there are some code like this inside protofile_pb.js

/**
 * Deserializes binary data (in protobuf wire format).
 * @param {jspb.ByteSource} bytes The bytes to deserialize.
 * @return {!proto.proto.Pong}
 */
proto.proto.Pong.deserializeBinary = function(bytes) {
  var reader = new jspb.BinaryReader(bytes);
  var msg = new proto.proto.Pong;
  return proto.proto.Pong.deserializeBinaryFromReader(msg, reader);
};


/**
 * Deserializes binary data (in protobuf wire format) from the
 * given reader into the given message object.
 * @param {!proto.proto.Pong} msg The message object to deserialize into.
 * @param {!jspb.BinaryReader} reader The BinaryReader to use.
 * @return {!proto.proto.Pong}
 */
proto.proto.Pong.deserializeBinaryFromReader = function(msg, reader) {
  while (reader.nextField()) {
    if (reader.isEndGroup()) {
      break;
    }
    var field = reader.getFieldNumber();
    switch (field) {
    case 1:
      var value = /** @type {number} */ (reader.readInt32());
      msg.setEvent(value);
      break;
    case 2:
      var value = /** @type {number} */ (reader.readInt64());
      msg.setId(value);
      break;
    default:
      reader.skipField();
      break;
    }
  }
  return msg;
};

im still trying how to map the incoming message

nb: protofile_pb.js is a converted file from protofile.proto using protoc