Netty实战读书笔记(第十一章(上))
来源:互联网 发布:醉虾 知乎 编辑:程序博客网 时间:2024/05/17 09:36
Netty提供的预制的Handler和编解码器。
Netty通过预制的SslHandler保证数据在pipeline中加密和解密,SslHandler在其他Handler的逻辑处理后才能进行加密。
import javax.net.ssl.SSLEngine;import io.netty.channel.Channel;import io.netty.channel.ChannelInitializer;import io.netty.handler.ssl.SslContext;import io.netty.handler.ssl.SslHandler;public class SslChannelInitializer extends ChannelInitializer<Channel>{private final SslContext context;private final boolean startTsl;public SslChannelInitializer(SslContext context , boolean startTsl){this.context = context;this.startTsl = startTsl;}@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stubSSLEngine engine = context.newEngine(ch.alloc());// 将channel的ch.pipeline().addFirst(new SslHandler(engine , startTsl));// sslHandler一般为pipeline的第一个handler,这样保证数据入站时 解密,出站最后加密。}}Netty提供了Http、Https的应用:
import io.netty.channel.Channel;import io.netty.channel.ChannelInitializer;import io.netty.handler.codec.http.HttpRequestDecoder;import io.netty.handler.codec.http.HttpRequestEncoder;import io.netty.handler.codec.http.HttpResponseDecoder;import io.netty.handler.codec.http.HttpResponseEncoder;public class HttpPipelineInitializer extends ChannelInitializer<Channel> {private boolean client ;@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stubif (client){ch.pipeline().addLast(new HttpRequestEncoder());// 客户端对于发送的编码。ch.pipeline().addLast(new HttpResponseDecoder());//客户端对于受到的消息解码。} else {ch.pipeline().addLast(new HttpResponseEncoder());// 服务器对于response编码ch.pipeline().addLast(new HttpRequestDecoder());// 客户端对于client的request解码。}}}在http请求中由于http可能有不同的部分组成,所以需要聚合不同的部分形成httpObject。
import io.netty.channel.Channel;import io.netty.channel.ChannelInitializer;import io.netty.handler.codec.http.HttpClientCodec;import io.netty.handler.codec.http.HttpServerCodec;/** * http自动聚合,将httpObject的不同部分聚合为一个HttpObject。 * @author pc * */public class HttpAggregationInitializer extends ChannelInitializer<Channel>{private boolean isClient;public HttpAggregationInitializer(boolean isClient){this.isClient = isClient;}@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stub// 如果是客户端,则添加HttpClientCodec().if (isClient){ch.pipeline().addLast("client" , new HttpClientCodec());} else {ch.pipeline().addLast("server" , new HttpServerCodec());}}}
Http压缩数据,在Netty中也提供了channelHandler用于数据压缩,webSocket。
import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInitializer;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.HttpClientCodec;import io.netty.handler.codec.http.HttpObjectAggregator;import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame;import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;import io.netty.handler.ssl.SslHandler;/** * webSocket 在一个单个的TCP连接上提供全双工的通信协议,代替http轮询请求的方式。 * @author pc * */public class WebSocketServerInitializer extends ChannelInitializer<Channel>{@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new SslHandler(null) , new HttpClientCodec() , // 提供最大为128kB的消息object。new HttpObjectAggregator(128 * 1024),// 如果请求以/webSocket 开头,则升级为websocket。new WebSocketServerProtocolHandler("/webSocket"), // 处理文本数据。new TextFrameHandler() , // 处理二进制数据。new BinaryFrameHandler());}private class TextFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {// TODO Auto-generated method stub// handler text data 。}}private class BinaryFrameHandler extends SimpleChannelInboundHandler<BinaryWebSocketFrame>{@Overrideprotected void channelRead0(ChannelHandlerContext ctx, BinaryWebSocketFrame msg) throws Exception {// TODO Auto-generated method stub// handler binary data 。}}}检测空闲连接与超时,能够最大限度的使用资源。
Netty的主要提供了几种用于检测超时与空闲连接的ChannelHandler的实现,主要有IdleStateHandler、ReadTimeOutHandler、WriteTimeOutHandler。
import java.util.concurrent.TimeUnit;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.Channel;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.timeout.IdleStateEvent;import io.netty.handler.timeout.IdleStateHandler;import io.netty.util.CharsetUtil;/** * IdleStateHandler实现。 * @author pc * */public class IdleStateHandlerInitializer extends ChannelInitializer{@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stub// IdleStateHandler发送心跳,在发送心跳之后60秒没有收到反馈则触发IdleEventState事件,通过重写userEventTriggered方法处理。ch.pipeline().addLast(new IdleStateHandler(0, 0, 60, TimeUnit.MILLISECONDS) , new HeartBeatHandler());}private static class HeartBeatHandler extends ChannelInboundHandlerAdapter{//发送到远程节点的心跳消息 private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer( "HEARTBEAT", CharsetUtil.ISO_8859_1));@Overridepublic void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {// 如果事件为IdleStateEvent事件,则。。。if (evt instanceof IdleStateEvent){ChannelFuture future = ctx.writeAndFlush(HEARTBEAT_SEQUENCE.duplicate());future.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);// 如果不是,则将它传给下一个ChannelHandler。} else {super.userEventTriggered(ctx, evt);}}}}
不同的协议帧的划分方法不同,一般分为按照分隔符划分、长度划分。
SMTP、POP3、IMAP按照分隔符划分帧,netty提供了handler分割符划分帧的类。
import io.netty.buffer.ByteBuf;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInitializer;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.LineBasedFrameDecoder;/** * * @author pc *RPC协议文本中有许多协议都是通过分割符定义不同的帧,比如(SMTP、POP3、IMAP)。 */public class LineBasedHandlerInitializer extends ChannelInitializer{@Overrideprotected void initChannel(Channel ch) throws Exception {// TODO Auto-generated method stub// 一些协议按照分割符编码字节流,LineBasedFrameDecoder将字节流按照分隔符分割为帧,将帧传入下一个handler。ch.pipeline().addLast(new LineBasedFrameDecoder(64 * 1024) , new FrameHandler());}private class FrameHandler extends SimpleChannelInboundHandler<ByteBuf>{@Overrideprotected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {// TODO Auto-generated method stub// do something handler。}}}RFC定义部分协议使用长度区分帧。
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
/**
*
* @author pc
* 基于长度的协议分帧。
*/
public class LengthBaseFrameInitializer extends ChannelInitializer{
@Override
protected void initChannel(Channel ch) throws Exception {
// TODO Auto-generated method stub
ChannelPipeline pipeline = ch.pipeline();
// 最大 的长度,开始的偏移量,没帧的长度。
pipeline.addLast(new LengthFieldBasedFrameDecoder(64 * 1024, 0, 8),
new LengthHandler());
}
private class LengthHandler extends SimpleChannelInboundHandler<ByteBuf>{
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
// TODO Auto-generated method stub
// do some handler。
}
}
}
- Netty实战读书笔记(第十一章(上))
- Netty实战读书笔记(第十一章(下))
- Netty实战读书笔记(第二章)
- Netty实战读书笔记(第三章)
- Netty实战读书笔记(第四章)
- Netty实战读书笔记(第六章)
- Netty实战读书笔记(第七章)
- Netty实战读书笔记(第七章)
- Netty实战读书笔记(第八章)
- Netty实战读书笔记(第十章)
- Netty实战读书笔记(第五章(一))
- Netty实战读书笔记(第五章(二))
- Netty实战读书笔记(第一章概念梳理)
- java编程思想读书笔记 第十一章(上)
- C和指针读书笔记(第十一章)
- 读书笔记(第十一讲)Encapsulation
- 第十一章:持有对象(上)
- Netty实战读书笔记四:Bootstrapping
- Describle
- PB数据窗口modify修改字段下拉属性
- jmeter接口参数化系列
- 关于Houdini ocean wave工具渲染结果无细节的解决方案
- 输入一个一维数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
- Netty实战读书笔记(第十一章(上))
- AIX系统下的topas命令使用
- 两个大整数相加
- 深入理解Java的接口和抽象类
- 深度学习ssd检测模型训练自己的数据集
- java中的三种对象代理 静态代理动态代理及cglib代理
- Druid学习笔记(2)Druid架构剖析
- spark单机版计算测试
- 获取主机信息