Google protocol Buffer Codec

ritom ritom at hotmail.com
Thu Jan 7 23:01:45 EST 2010


Jannick,
Thanks for taking time to write the sample for me. 

Trustin,
You always amaze me I only started using netty because you were on the team.
I could now see Mina on the small corner of the world down the road. I only
wish we could have some one take initiative to upgrade quickfix/j to the
netty implementation with Java 1.5.

I took Jannick's advice and wrote a RequestProtocol and ResponseProtocol
request is for sending messages to server which consist of multiple objects
and Response to get the response back from server and it works like charm.

Thanks a lot.


Thingfish wrote:
> 
> Hi again :)
> 
> Made a quick example of doing the same thing Trustin just demonstrated, by
> using the protobuf union type/wrapper trick. Should note that protobuf
> does
> not (and can not be made to) generate any code to provide easy handling
> for
> this approach, so its a bit cumbersome. Okay, to the example, lets say you
> want to send the messages Foo and Bar. The trick is to define a "union
> type"
> or a sort of a container that you put your actual message inside:
> 
> message Foo{
> optional string some_field = 1;
> }
> 
> message Bar{
> optional string some_other_field = 1;
> }
> 
> 
> message MessageWrapper{
> enum Type {FOO = 1; BAR = 2; }
> required Type type = 1;
> 
> optional Foo foo = 2;
> optional Bar bar = 3;
> }
> 
> 
> So when you want to send a Foo message, you construct the Foo message as
> usual, and then wrap it inside a MessageWrapper mesage. You then have to
> adhere to the convention, that always
>  1) Set just one of the optional fields
>  2) Set the Type field to the enum representing that field.
> 
> For example to send Foo:
> 
> Foo fooMsg =
> Foo.newBuilder().
> setSomeField("SomeValue").
> build();
>  MessageWrapper wrapperMsg =
> MessageWrapper.newBuilder().
> setType(Type.FOO).
> setFoo(fooMsg).
> build();
> 
> someChannel.write(wrapperMsg);
> 
> Note: It's important that you always remember to wrap the messages you
> send,
> otherwise you get a very strange behavior.
> 
> You then setup your pipeline with a handler to receive this wrapper
> message:
> p.addLast("protobufDecoder", new
> ProtobufDecoder(MessageWrapper.getDefaultInstance()));
> 
> and in your application specific handler do something like:
> 
> public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
> MessageWrapper wrapperMsg = (MessageWrapper)e.getMessage();
>  switch (wrapperMsg.getType()){
>  case FOO:
> Foo fooMsg = wrapperMsg.getFoo();
> //Handle a Foo message
> break;
>  case BAR:
> Bar barMsg = wrapperMsg.getBar();
> //Handle a Bar message
> break;
>  default:
> throw new IllegalArgumentException("..... Type: " + wrapperMsg.getType());
>  }
>  }
> 
> 
> Hope this helps. Will see if I can find time to put a complete sample
> together.
> 
> Regards
> Jannick
> 
> 
> 2010/1/7 "Trustin Lee (이희승)" <trustin at gmail.com>
> 
>> Tom,
>>
>> I would write a custom decoder instead of using ProtobufDecoder in such
>> a case; something like the following, which prepends the message type
>> and the message length field:
>>
>> public class MyProtobufDecoder extends FrameDecoder {
>>
>>  boolean waitingForHeader;
>>  int msgType;
>>  int msgLength;
>>
>>  Message prototypeA =
>>      MessageA.getDefaultInstance().getDefaultInstanceForType();
>>  Message prototypeB =
>>      MessageB.getDefaultInstance().getDefaultInstanceForType();
>>  Message prototypeC =
>>      MessageC.getDefaultInstance().getDefaultInstanceForType();
>>
>>  @Override
>>  protected Object decode(ctx, msg) {
>>    ChannelBuffer buf = (ChannelBuffer) msg;
>>    if (waitingForHeader) {
>>      // Wait until at least 5 bytes are received in the buffer
>>      if (buf.readableBytes() < 5) {
>>        return null;
>>      }
>>      msgType = buf.readByte();
>>      msgLength = buf.readInt();
>>      waitingForHeader = false;
>>    }
>>
>>    if (!waitingForHeader) {
>>      ChannelBuffer pbmsg = buf.readBytes(msgLength);
>>      Message prototype;
>>      switch (msgType) {
>>      case 0: prototype = prototypeA; break;
>>      case 1: prototype = prototypeB; break;
>>      case 2: prototype = prototypeC; break;
>>
>>      // This is a user defined exception.
>>      // Handle this exception in exceptionCaught()
>>      // in your terminal handler
>>      default: throw new ProtocolViolationException();
>>      }
>>
>>      try {
>>        return prototype.newBuilderForType().mergeFrom(
>>                    new ChannelBufferInputStream(pbmsg)).build();
>>      } finally {
>>        waitingForHeader = true;
>>      }
>>    }
>>  }
>> }
>>
>> You will have to learn how to write a decoder eventually to customize
>> the protocol to meet your need.  The user guide and the factorial
>> example is a good starting point.
>>
>> However, I would still recommend the solution Jannick provided.
>>
>> HTH,
>> Trustin
>>
>> ritom wrote:
>> > Thanks for very much for the insight. If you do have multiple messages
>> how to
>> > you handle them in the decoder. In the example looks like everything is
>> > based on one object what if you have two message type Foo and Bar
>> instead
>> of
>> > LocalTimeProtocol alone. Can you please give a example. Thanks a lot in
>> > advance.
>> >
>> >   p.addLast("protobufDecoder", new
>> > ProtobufDecoder(LocalTimeProtocol.Locations.getDefaultInstance()));
>> >
>> >
>> > Thingfish wrote:
>> >> Hi
>> >>
>> >> The easiest solution is to wrap all your messages in a 'union type' as
>> >> described in this protobuf tutorial:
>> >>
>> http://code.google.com/intl/da-DK/apis/protocolbuffers/docs/techniques.html#union
>> >>
>> >> Alternatively you will have to manually prepend some kind of command
>> id
>> to
>> >> identity the kind of protobuf message being sent, but unlikely to be
>> worth
>> >> the trouble.
>> >>
>> >>
>> >> Regards
>> >> Jannick
>> >> <
>> http://code.google.com/intl/da-DK/apis/protocolbuffers/docs/techniques.html#union
>> >
>> >>
>> >> 2010/1/2 ritom <ritom at hotmail.com>
>> >>
>> >>> Can somebody please help me understand the google protobuf support
>> within
>> >>> Netty.
>> >>> In the LocalTimeServerPipelineFactory example we have
>> >>>
>> >>> p.addLast("protobufDecoder", new
>> >>> ProtobufDecoder(LocalTimeProtocol.Locations.getDefaultInstance()));
>> >>>
>> >>> That would mean we can now receive the Locations message in
>> >>> TimeServerHandler.
>> >>>
>> >>>  public void messageReceived(ChannelHandlerContext ctx, MessageEvent
>> e)
>> {
>> >>>        Locations locations = (Locations) e.getMessage();
>> >>>
>> >>> How would I implement support for multiple incoming message types
>> where
>> >>> you
>> >>> might be receiving different types of request from the client. Lets
>> say
>> >>> you
>> >>> are receiving Logon first then BalanceRequest, TransferRequest and so
>> on.
>> >>> Also server will reply with multiple Message Types depending on the
>> >>> request.
>> >>> Can somebody please please help.
>> >>>
>> >>> Tom
>> >>> --
>> >>> View this message in context:
>> >>>
>> http://n2.nabble.com/Google-protocol-Buffer-Codec-tp4241485p4241485.html
>> >>> Sent from the Netty User Group mailing list archive at Nabble.com.
>> >>> _______________________________________________
>> >>> netty-users mailing list
>> >>> netty-users at lists.jboss.org
>> >>> https://lists.jboss.org/mailman/listinfo/netty-users
>> >>>
>> >> _______________________________________________
>> >> netty-users mailing list
>> >> netty-users at lists.jboss.org
>> >> https://lists.jboss.org/mailman/listinfo/netty-users
>> >>
>> >>
>> >
>>
>> --
>> what we call human nature in actuality is human habit
>> http://gleamynode.net/
>>
>>
>>
>> _______________________________________________
>> netty-users mailing list
>> netty-users at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/netty-users
>>
>>
> 
> _______________________________________________
> netty-users mailing list
> netty-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/netty-users
> 
> 

-- 
View this message in context: http://n2.nabble.com/Google-protocol-Buffer-Codec-tp4241485p4270424.html
Sent from the Netty User Group mailing list archive at Nabble.com.



More information about the netty-users mailing list