原创:
同事倒腾出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.真心不好扩展。
所以哩,我加了个类转化成我想要的对象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文件,这样就很轻松了。