Protobuf报错Protocol message tag had invalid wire type

做李林峰的protobuf版本的图书订购服务这个案例,使用protobuf报错如下

io.netty.handler.codec.DecoderException: com.google.protobuf.InvalidProtocolBufferException$InvalidWireTypeException: Protocol message tag had invalid wire type.
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:697)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:632)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:549)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:511)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:918)
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
	at java.lang.Thread.run(Thread.java:748)
Caused by: com.google.protobuf.InvalidProtocolBufferException$InvalidWireTypeException: Protocol message tag had invalid wire type.
	at com.google.protobuf.InvalidProtocolBufferException.invalidWireType(InvalidProtocolBufferException.java:111)
	at com.google.protobuf.UnknownFieldSet$Builder.mergeFieldFrom(UnknownFieldSet.java:557)
	at com.google.protobuf.GeneratedMessageV3.parseUnknownField(GeneratedMessageV3.java:313)
	at com.xyzla.netty.codec.protobuf.SubscribeReqProto$SubscribeReq.<init>(SubscribeReqProto.java:153)
	at com.xyzla.netty.codec.protobuf.SubscribeReqProto$SubscribeReq.<init>(SubscribeReqProto.java:77)
	at com.xyzla.netty.codec.protobuf.SubscribeReqProto$SubscribeReq$1.parsePartialFrom(SubscribeReqProto.java:1017)
	at com.xyzla.netty.codec.protobuf.SubscribeReqProto$SubscribeReq$1.parsePartialFrom(SubscribeReqProto.java:1011)
	at com.google.protobuf.AbstractParser.parsePartialFrom(AbstractParser.java:158)
	at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:191)
	at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:197)
	at com.google.protobuf.AbstractParser.parseFrom(AbstractParser.java:48)
	at io.netty.handler.codec.protobuf.ProtobufDecoder.decode(ProtobufDecoder.java:121)
	at io.netty.handler.codec.protobuf.ProtobufDecoder.decode(ProtobufDecoder.java:65)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88)
	... 16 more

原因是注释掉了

ch.pipeline().addLast( new ProtobufVarint32FrameDecoder());

具体原因为**ProtobufDecoder仅仅负责解码**,它不支持读半包。因此,在ProtobufDecoder前面,一.定要有能够处理读半包的解码器,有以下三种方式可以选择。

  1. 使用Netty提供的ProtobufVarint32FrameDecoder,它可以処理半包消息;
  2. 继成Netty提供的通用半包解码器LengthFieldBasedFrameDecoder;
  3. 继承ByteToMessageDecoder炎,自己处理半包消息。

如果你只使用ProtobufDecoder解码器而忽略对半包消息的处理,程序是不能正常エ作的。取消注释ProtobufVarint32FrameDecoder即可。

Protobuf报错Protocol message tag had invalid wire type

  • qq_43638135
    妲己再美究为妃: 博主没有想过自己接一些私活干吗?我现在还没毕业,但是我也确实听说外挂市场自动化游戏脚本市场挺火热的,并且报酬也很丰厚,但是具体的我也不是很清楚,求解答。 (1个月前 #47楼) 查看回复(2) 举报 回复
    22