V
V
Vitaly Yakovenko2015-09-30 21:33:25
Google
Vitaly Yakovenko, 2015-09-30 21:33:25

Google Protobuf - how to determine the type of incoming message?

I'm learning protobuf, I ran into such a disaster. Let's say we have this .proto:

syntax = "proto3";
package example;
message Kaboom {
    uint64 data = 1;
}
message Oops {
    uint64 data = 1;
}

Messages are sent over WebSocket between a Golang server and a JavaScript client.
The server is waiting for new commands from the client, and the client can send both Kaboom and Oops. The server cannot know in advance what type of message will come, and here the question arises, how to deserialize data that came via WebSocket without knowing the type in advance?
I met somewhere an article from 2011, where a similar question was advised to create a message wrapper in which to include existing types, and on the server side to check which field is filled. For some reason it seems to me that this solution is far from optimal.
I hope for useful advice, thanks for reading.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
SilentFl, 2015-10-01
@Xazzzi

generally speaking, you can do it through the message wrapper, but it seems like it’s more correct to do it through Oneof, you can study an example on go here . message type selection is strings

// Use a type switch to determine which oneof was set.
  switch u := test.Union.(type) {
  case *pb.Test_Number: // u.Number contains the number.
  case *pb.Test_Name: // u.Name contains the string.
  }

F
Fadi Haj, 2017-02-15
@fdhaj

You can make a `kind` field.

syntax = "proto3";

package entity;

message Entity {
  // Kinds:
  //
  // * kaboom
  // * oops
  string kind = 1;

  message Kaboom { uint64 data = 1; }

  message Oops { uint64 data = 1; }

  Kaboom kaboom = 2;

  Oops oops = 3;
}

package main

import (	
  "github.com/golang/protobuf/proto"
  
  "pathtopkg/entity"
)

func main() {
  var e entity.Entity

  err := proto.Unmarshal(buf, &e)
  if err != nil {
    panic(err)
  }

  switch e.Kind {
  case "kaboom":
    // Kaboom
  case "oops":
    // Oops
  default:
    panic("Invalid kind")
  }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question