Protobuf-CSharp Port

I am using the Jon Arch port (excellent) of the Google Protocol protocol port for C # /. Net.

For practice, I wrote an instant messenger app that sends messages over a socket. I have a message definition as follows: -

message InstantMessage {<br/> required string Message = 1;<br/> required int64 TimeStampTicks = 2; <br/> } 

When the sender serializes the message, he sends it really elegantly: -

  ... InstantMessage.Builder imBuild = new InstantMessage.Builder(); imBuild.Message = txtEnterText.Text; imBuild.TimeStampTicks = DateTime.Now.Ticks; InstantMessage im = imBuild.BuildPartial(); im.WriteTo(networkStream); ... 

This works great. But on the other hand, it’s hard for me to work ParseFrom .

I want to use: -

 InstantMessage im = InstantMessage.ParseFrom(networkStream); 

But instead, I had to read it in bytes, and then parse it here. This is obviously not ideal for a number of reasons. Current Code: -

 while (true) { Byte[] byteArray = new Byte[10000000]; int intMsgLength; int runningMsgLength = 0; DateTime start = DateTime.Now; while (true) { runningMsgLength += networkStream.Read(byteArray, runningMsgLength, 10000000 - runningMsgLength); if (!networkStream.DataAvailable) break; } InstantMessage im = InstantMessage.ParseFrom(byteArray.Take(runningMsgLength).ToArray()); 

When I try to use ParseFrom , the control does not return to the calling method even when I know that a valid GB message is on the wire.

Any advice would be greatly appreciated.

Pw

+4
source share
2 answers

I apologize for the time to answer this. As Mark says, there is no terminator in the protocol buffers, and they are not a length prefix if they are not nested. However, you can put on the length prefix yourself. If you look at MessageStreamIterator and MessageStreamWriter, you will see how I do it - basically I pretend that I am in the middle of the message, writing the attached message as field 1. Unfortunately, I have to use internal details when reading the message (BuildImpl).

Now there is another API for this: IMessage.WriteDelimitedTo and IBuilder.MergeDelimitedFrom . This is probably what you want at the moment, but I seem to remember that it has a small problem in terms of detecting the end of the stream (i.e. when there is no other message to read). I can’t remember if there is a fix at the moment - I have a feeling that it has changed in the Java version, and I may not have ported this change yet. In any case, this is definitely an area to look at.

+4
source

Protobuf does not have a terminator - so either close the stream, or use your own length prefix, etc. Protobuf-net provides this easily through SerializeWithLenghtPrefix / DeserializeWithLengthPrefix.

Simple: without this, he cannot know where each message ends, so he continues to read at the end of the stream.

0
source

All Articles