原创:
同事倒腾出netty中用到protobuf,自己突然很想尝试自己搭建一个;以下是搭建成果。
.proto文件
package bytebuf; option java_package = "bytebuf"; option java_outer_classname = "Msg"; message MyMessage { optional int32 handler = 1; optional int32 cmd = 2; }
用com.google.protobuf-2.4.0.jar 版本很重要哦。(之前版本问题,加载java类的时候,老爆红)
bat:文件
D: protoc --java_out=. *.proto pause
然后:netty工程下的factory
public class Factory implements ChannelPipelineFactory { public ChannelPipeline getPipeline() throws Exception { ChannelPipeline p = Channels.pipeline(); p.addLast("frameDecoder", new ObjectDecoder()); // p.addLast("protobufDecoder", new ProtobufDecoder(Msg.MyMessage.getDefaultInstance())); // p.addLast("frameEncoder", new ProtobufVarint32LengthFieldPrepender()); p.addLast("protobufEncoder", new ProtobufEncoder()); p.addLast("handler", new Handler()); return p; } }
之前new ProtobufDecoder(Msg.MyMessage.getDefaultInstance 和 ProtobufVarint32LengthFieldPrepender 都得注掉。。。。坑爹呀,被网上的博文忽悠的好惨。
如果用new ProtobufDecoder(Msg.MyMessage.getDefaultInstance ,后面的只能读取Msg.MyMessage.真心不好扩展。
扫描二维码关注公众号,回复:
1260176 查看本文章
所以哩,我加了个类转化成我想要的对象Message
public class Message<T> { public int handler = 0; public int cmd = 0; public T body ; //我的protobuf类 }
为啥我要用ObjectDecoder解码哩~
因为
public class ObjectDecoder extends FrameDecoder { @Override protected Object decode(ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception { short cmd = buffer.readShort(); Message msg1 = new Message(); msg1.handler = cmd; //可以有个Map容器,根据cmd获得不同的protobuf类,赋给msg1.body, 因为msg1.body的类型是T。 Msg.MyMessage msg = Msg.MyMessage.parseFrom(buffer.array()); msg1.body = msg; eturn msg1; } }
在Handler类里
public class Handler extends SimpleChannelUpstreamHandler { Message msg = (Message) e.getMessage(); //也可以在map容器里根据msg.cmd的值,获得指定的protobuf类 Msg.MyMessage msg1 = (Msg.MyMessage)msg.body; System.err.println( " , handler = " + msg1.getHandler() + " , cmd = " + msg1.getCmd()); }
client:
public static void main(String[] args) throws Exception { Socket socket = new Socket(); socket.connect(new InetSocketAddress(9090)); OutputStream out = socket.getOutputStream(); ByteArrayC bc = new ByteArrayC(); Msg.MyMessage.Builder msg = Msg.MyMessage.newBuilder(); msg.setHandler(35); msg.setCmd(25); bc.writeShort(50); bc.writeByteArray(msg.build().toByteArray()); out.write(bc.toArray()); Thread.sleep(50 * 60 * 1000); }
netty下可以使用不同的protobuf文件,这样就很轻松了。