1、前言
一般使用 protobuf 的原因是因为快,然后我之前对 netty 的概念并不熟悉,不知道怎么使用编解码。所以。。。
对于编解码的顺序,inbound 是顺序执行,outbound 是逆序执行。
2、代码
在 《netty in action》那本书中说了编解码这章节,里面提到了通过 protobuf 进行序列话,提供了2个编码器,两个解码器,都是配合使用的。
对于发送端(先发送后接收),使用 ProtobufEncoder、ProtobufVarint32LengthFieldPrepender 来进行编码,对于接收端(先接收后发送),使用 ProtobufVarint32FrameDecoder、ProtobufDecoder 来解码。
发送端:
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline()
//10 秒没发送消息 将IdleStateHandler 添加到 ChannelPipeline 中
.addLast(new IdleStateHandler(0, 10, 0))
//心跳解码
//.addLast(new HeartbeatEncode())
// google Protobuf 编解码
//拆包解码
.addLast(new ProtobufVarint32FrameDecoder())
.addLast(new ProtobufDecoder(CIMResponseProto.CIMResProtocol.getDefaultInstance()))
//
//拆包编码
.addLast(new ProtobufVarint32LengthFieldPrepender())
.addLast(new ProtobufEncoder())
.addLast(new CIMClientHandle())
;
}
})
;
ChannelFuture future = null;
future = bootstrap.connect(cimServer.getIp(), cimServer.getCimServerPort()).sync();
接收端:
ServerBootstrap bootstrap = new ServerBootstrap()
.group(boss, work)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(nettyPort))
//保持长连接
.childOption(ChannelOption.SO_KEEPALIVE, true)
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline()
//11 秒没有向客户端发送消息就发生心跳
.addLast(new IdleStateHandler(11, 0, 0))
// google Protobuf 编解码
.addLast(new ProtobufVarint32FrameDecoder())
.addLast(new ProtobufDecoder(CIMRequestProto.CIMReqProtocol.getDefaultInstance()))
.addLast(new ProtobufVarint32LengthFieldPrepender())
.addLast(new ProtobufEncoder())
.addLast(new CIMServerHandle());
}
});
ChannelFuture future = bootstrap.bind().sync();
if (future.isSuccess()) {
LOGGER.info("Start cim server success!!!");
}
``
网友评论