netty客户端和服务端, 都需要继承SimpleChannelInboundHandler 或者实现ChannelInboundHandler或者继承ChannelInboundHandlerAdapter
先看下这两个类的区别:
io.netty.channel.ChannelInboundHandler;
io.netty.channel.SimpleChannelInboundHandler;
io.netty.channel.ChannelInboundHandlerAdapter;
这三个类的继承关系如下:
io.netty.channel.ChannelInboundHandler;
ChannelInboundHandlerAdapter 对 ChannelInboundHandler进行了封装,
SimpleChannelInboundHandler 又对ChannelInboundHandlerAdapter 进行了封装
再看源码:
ChannelInboundHandlerAdapter 中 channelRead的参数msg类型为Object类型(需接收ByteBuf类型,其他类型接收不到),
而SimpleChannelInboundHandler用传进来的泛型 对 Object msg 进行了处理,使得channelRead0的参数可以为以下效果
这就是实现SimpleChannelInboundHandler 和ChannelInboundHandlerAdapter 在channelRead上的区别;
netty是以byteBuf类型传输的 ,所以在传输前后要对传输的信息进行编码,解码.
public class NettyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new StringDecoder());// 当信息进入服务端的handler之前进行解码
pipeline.addLast(new StringEncoder());// 当信息从服务端发送出去之前进行编码
//pipeline.addLast(new ObjectDecoder(10240, ClassResolvers.cacheDisabled(null)));
pipeline.addLast(new NettyServerHandler());//前面的顺序可以调换,但这个一定是最后添加
}
});
System.out.println("netty server start。。");
ChannelFuture channelFuture = serverBootstrap.bind(9000).sync();
channelFuture.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
对象类型传输:(序列化操作慢)
ctx.writeAndFlush(new User(1,"zhangsan")); // 客户端直接传输对象
pipeline.addLast(new ObjectEncoder()); // 客户端进行编码
pipeline.addLast(new NettyClientHandler());
pipeline.addLast(new ObjectDecoder(10240, ClassResolvers.cacheDisabled(null)));// 解码
pipeline.addLast(new NettyServerHandler()); // 服务端
对象使用Protostuff传输(序列化快) 序列化工具类:
ByteBuf buf = Unpooled.copiedBuffer(ProtostuffUtil.serializer(new User(1, "zhangsan")));
ctx.writeAndFlush(buf); // 客户端
ByteBuf buf = (ByteBuf) msg;
byte[] bytes = new byte[buf.readableBytes()];
buf.readBytes(bytes);
ProtostuffUtil.deserializer(bytes, User.class); // 服务端对收到的对象解码