概述
去Google的protocol buffers简单的绕了一圈终于回来了,大致的了解了protobuf的用法,现在回来和Netty集成在一起看看到底有多香!
Netty集成protobuf
Netty的客户端和服务端传递数据的demo已经写了几个了,对Netty在使用上的套路已经有了很清楚的认识:注意各种场景下的Handler使用、重写ChannelInboundHandlerAdapter中各个管道状态的回调方法(channelRegistered、channelUnregistered、channelRead0等)......这里就不在赘述客户端和服务端怎么编写的了。
服务端:
package com.leolee.netty.sixthExample;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.net.InetSocketAddress;
/**
* @ClassName TestServer
* @Description: 基于protobuf的服务端
* @Author LeoLee
* @Date 2020/9/2
* @Version V1.0
**/
public class TestServer {
public static void main(String[] args) throws InterruptedException {
//定义线程组 EventLoopGroup为死循环
//boss线程组一直在接收客户端发起的请求,但是不对请求做处理,boss会将接收到的请i交给worker线程组来处理
//实际可以用一个线程组来做客户端的请求接收和处理两件事,但是不推荐
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
//启动类定义
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
//子处理器,自定义处理器,服务端可以使用childHandler或者handler,handlerr对应接收线程组(bossGroup),childHandler对应处理线程组(workerGroup)
.handler(new LoggingHandler(LogLevel.INFO))//日志处理器
.childHandler(new TestServerInitializer());
//绑定监听端口
ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync();
//定义关闭监听
channelFuture.channel().closeFuture().sync();
} finally {
//Netty提供的优雅关闭
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
package com.leolee.netty.sixthExample;
import com.leolee.protobuf.DataInfo;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
/**
* @ClassName TestServerInitializer
* @Description: TODO
* @Author LeoLee
* @Date 2020/9/2
* @Version V1.0
**/
public class TestServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("protobufVarint32FrameDecoder", new ProtobufVarint32FrameDecoder());
pipeline.addLast("protobufDecoder", new ProtobufDecoder(DataInfo.Student.getDefaultInstance()));
pipeline.addLast("protobufVarint32LengthFieldPrepender", new ProtobufVarint32LengthFieldPrepender());
pipeline.addLast("protobufEncoder", new ProtobufEncoder());
pipeline.addLast(new TestServerHandler());
}
}
package com.leolee.netty.sixthExample;
import