Closed chrispytoes closed 2 months ago
Small side note: style is to rename your protobuf package import into pb
(if you import more than one, then some sort of abbreviation + pb
, so like field_office_operations_proto
would be foopb
), to reduce the number of characters of a sequence that usually ends up appearing in a lot of the code.
Could you provide the actual stacktrace from the panic when you access update.EntityCreates[0]
?
What are the values you’re feeding into &protobuf.EntityCreate{}
? Any of the values that are the zero value, will be omited from the prototext
render you’ll get from fmt.Sprint(&pb.FooMessage{})
, and if all the values are zero values, then it should end up being an empty string. If you could share the results from the fmt.Println(*entity)
that would help.
Adding onto that last paragraph, it’s recommended to make your first Enum value INVALID
or UNKNOWN
or some other value that is clearly not valid data. Since this will be the zero value, it’s the value that won’t (by default) show up in prototext
or protojson
. It’s best when that omitted value is an invalid value, rather than a valid value.
In the end, I’m pretty sure based on the symptoms you describe that you’re running into “zero values are omitted from marshalled data”. But without the above extra details it’s hard to be 100% sure.
but the
EntityCreates
array inside is still empty.
Does it have len(EntityCreates) == 0
or when you print it out it’s []
empty?
@puellanivis Okay, we may be getting somewhere because I didn't know zero values were excluded when printing. Yes all of the data was default zero values in this particular case. However, I just tested again hardcoding in some non-zero values, and while the data does actually print now when I log the struct, the client still gets an empty array.
The client receiving this data is in JavaScript, so it's pretty clear there that it's an empty array, and it is still getting an empty array even when sending the message with non-zero data.
With the non-zero data hardcoded in, if I print the update
variable right before marshaling, it does print data now:
update := &pb.FrameUpdate{
EntityCreates: make([]*pb.EntityCreate, len(g.EntityCreates)),
}
for i := range len(g.EntityCreates) {
update.EntityCreates[i] = <-g.EntityCreates
}
fmt.Println(update) // This does print the expected data now
data, err := proto.Marshal(update)
if err == nil {
err = c.WriteMessage(websocket.BinaryMessage, data) // Client receives and parses this message, but still, `entityCreates` is empty
}
The issue was with my client, I was not decoding the message correctly and it wasn't giving me an error to indicate that. However the fact that zero values were not printing did throw me off in thinking the issue was with the server.
I'm really sorry for the bad title but I really have no idea what's happening here, none of this makes any sense.
I am new to protobuf, and I am having trouble with the generated message types. I am trying to prepare messages in one goroutine, put them in a channel, and collect them in another goroutine to package them into the final message to send back.
However when I pull the messages out of the channel to put them into a slice for the final message, the slice is still empty (but still has length of 1):
Finally, when I parse these messages out on the receiving end, I get the
FrameUpdate
object but theEntityCreates
array inside is still empty.This is my protoc command:
protoc --experimental_allow_proto3_optional --go_opt=paths=source_relative -I=./proto-schema --go_out=./proto ./proto-schema/messages.proto