为什么80%的码农都做不了架构师?>>>
Netty 实现基于google-protocol-buffer自定义消息格式
首先自己定义一个消息格式:
package fhq;
option java_package = "com.wesker.protocol";
option java_outer_classname = "ProtocolTypeMessage";
enum ProtocolType{
EXCEPTION = 1;
INFO = 2;
SHUTDOWN = 3;
EVALUATE_TO_TYPESET = 4;
EVALUATE_TO_MATHML = 5;
}
package fhq;
option java_package = "com.wesker.protocol";
option java_outer_classname = "ProtocolMessage";
import "ProtocolTypeMessage";
message Protocol {
required ProtocolType type = 1;
required bytes data = 2;
}
这里的Protocol就是我们要处理的消息了。type是消息类型,data是数据。接下来生成java代码:
protoc --java_out=/home/michael/protocol/ ProtocolTypeMessage
protoc --java_out=/home/michael/protocol/ ProtocolMessage
接下来就是定义基于netty的消息转换器了,一个编码:将自定义的消息转换成byte[]。 这里用范型指定我们刚才定义好的消息类型。
public class MessageEncoder extends MessageToByteEncoder{
@Override
protected void encode(ChannelHandlerContext context, Protocol protocol, ByteBuf out)
throws Exception {
byte[] data = protocol.toByteArray();
out.writeInt(data.length);
out.writeBytes(data);
}
}
一个解码:将byte[]转换成自定义的消息
public class MessageDecoder extends ByteToMessageDecoder {
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List
在初始化server的时候将这2个东西放进去,和一个server处理自定义消息的handler
public class MyServerHandler extends SimpleChannelInboundHandler{
@Override
protected void messageReceived(ChannelHandlerContext arg0, Protocol arg1) throws Exception {
//do something.....
}
}
ServerBootstrap boot = new ServerBootstrap();
boot.group(core.getBoss(), core.getWorker()).channel(NioServerSocketChannel.class).childHandler(new ChannelInitializer(){
@Override
protected void initChannel(SocketChannel ch)
throws Exception {
ChannelPipeline p = ch.pipeline();
SSLEngine engine = core.getSslContext().createSSLEngine();
engine.setUseClientMode(false);
p.addLast("ssl", new SslHandler(engine));
p.addLast(new LoggingHandler(LogLevel.INFO));
p.addLast("encoder", new MessageEncoder());//在这里
p.addLast("decoder", new MessageDecoder());//在这里
p.addLast("MyServerHandler", new MyServerHandler());//server端处理消息
}});
同样客户端也要做同样的事情:
public class MyClientHandler extends SimpleChannelInboundHandler{
@Override
protected void messageReceived(ChannelHandlerContext arg0, Protocol arg1) throws Exception {
//do something.....
}
}
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(core.getGroup()).channel(NioSocketChannel.class)
.handler(new ChannelInitializer(){
@Override
protected void initChannel(SocketChannel ch)
throws Exception {
ChannelPipeline p = ch.pipeline();
SSLEngine engine = core.getSslContext().createSSLEngine();
engine.setUseClientMode(true);
p.addLast("ssl", new SslHandler(engine));
p.addLast("encoder", new MessageEncoder());//这里
p.addLast("decoder", new MessageDecoder());//这里
p.addLast("MyClientHandler", new MyClientHandler());//client端处理消息
}});
到这里你就可以使用自己的消息格式了。
Netty 4以后都自带了对google-protocol-buffer的解析器 :
ProtobufDecoder ProtobufEncoder
懒得自己定义就用这个。需要注意的是,ProtobufDecoder需要一个protocol-buffer的实例来才能初始化。(调用getDefaultInstance())
写的非常仓促。。。。。。可能好多地方没有写明白。。有什么问题大家可以圈我。