Netty权威指南 第2版学习笔记9——Channel,Unsafe和 AttributeMap
来源:互联网 发布:诺基亚6730c软件 编辑:程序博客网 时间:2024/05/22 00:22
Channel功能说明
io.netty.channel.Channel是Netty网络操抽象类,它聚合了一组功能,包括但不限于网络的读、写,客户端发起连接,主动关闭连接,链路关闭,获取通信双方的网络地址等。它也包含了Netty框架相关的一些功能框架,包括获取该Channel的EventLoop,获取缓冲分配器ByteBufAllocator和pipeline等。
Channel的工作原理
Channel网络I/O相关的方法定义:
- Channel read():从当前的Channel中读取数据到第一个inbound缓冲区中,如果数据被成功读取,触发ChannelHandler.channelRead(ChannelHandlerContext,Object)事件,读取操作API调用完成之后,紧接着会触发ChannelHanler.channelReadComplete(ChannelHandlerContext)事件,这样业务的ChannelHandler可以决定是否需要继续读取数据。如果已经有读操作表求被挂起,则后续的读操作会被忽略。
- ChannelFutrue write(Object msg):当前的msg通过ChannelPipeline写入到目标Channel中。这时并没有立刻发送,要flush操作才会被写入到Channel中,发送给对方。
- ChannelFuture write(Object msg,ChannelPromise promise):功能同write(Object msg),但携带了ChannelPromise参数负责设置写入操作的结果。
- ChannelFuture writeAndFlush(Object msg,ChannelPromise promise):相当于write+flush
- ChannelFuture writeAndFlush(Object msg)
- Channel flush:写入到发送环形数组中的消息全部与入到目标Channel中。
- ChannelFuture close(ChannelPromise promise):主动关闭发前连接,通过Channel Promise 设置操作进行结果通知,无论操作是否成功,都可以通过ChanelPromise获取操作结果。该操作会级联触发ChannelPipeline中所有ChannelHnadler的ChannelHandler.close(ChannelHandlerContext,ChannelPromise)事件。
- ChannelFuture disconnect(ChannelPromise promise):请求断开与远程通信对端的连接并使用ChannelPromise 来获取操作结果的通知消息。该方法会级联触发ChannelHandler.disconnect(ChannelHandlerContext,ChannelPromise)事件。
- ChannelFuture connect(SocketAddress remoteAddress):客户端使用指定的服务端地址remoteAddress发起连接请求,如果连接因为应答超时而失败,ChannelFuture中的操作结果就是ConnectTimeoutException异常。 如果连接被拒绝,操作结果为ConnectException。该方法级联触发ChannelHandler.connect(ChannelHandlerContext,SocketAddress,SocketAddress,ChannelPromise)事件。
- ChannelFuture connect(SocketAddress remoteAddress,SocketAddress localAddress):与方法(9)功能类似,需要先绑定指定的本地地址
- ChannelFuture connect(SocketAddress remoteAddress,ChannelPromise promise)
- connect(SocketAddress remoteAddress,SocketAddress localAddress,ChannelPromise promise)
- ChannelFuture bind(SocketAddress localAddress)
- ChannelFuture bind(SocketAddress localAddress,ChannelPromise promise)
- ChannelConfig config():获取当前Channel的配置信息
- boolean isOpen():判断当前Channel是否已经打开
- boolean isRegistered():判断当前Channel是否已经注册到EventLoop上
- boolean isActive():判断当前Channel是否已经处于激活状态
- ChannelMetadata metadata():获取当前Channel的元数据描述信息,包括TCP参数配置等
- SocketAddress localAddress():获取当前Channel的本地绑定地址
- SocketAddress remoteAddress():获取当前Channel的远程Socket地址
Unsafe接口是Channel的一个内部接口,不应该被用户调用。
其它重要的API功能说明
eventLoop()
Channel需要注册到EventLoop的多路复用器上,用于处理I/O事件,通过eventLoop方法中以获取到Channel注册的EventLoop。EventLoop本质上就是处理网络读写事件的Reactor线程。在Netty中,它不仅仅用来处理网络事件,也可以用来执行定时任务和用户自定义NioTask等任务 。
metadata()
通过metadata()方法和来获取当前Channel的TCP参数配置
parent()
对于服务端的Channel而言,它的父Channel为空。对于客户端Channel,它的父Channel是创建它的ServerSocketChannel
id()
用来获取Channel标识,生成策略可能是:
- 机器的MAC地址
- 当前的进程ID
- 当前系统时间的毫秒
- 当前系统时间纳秒数
- 32位的随机整形数
- 32位自增的序列数
其它说明
服务端NioServerSocketChannel继承关系
客户端NioSocketChannel的继承关系类图
AttributeMap
AttributeMap是绑定在Channel或者ChannelHandlerContext上的一个附件。
ChannelHandlerContext都是ChannelHandler和ChannelPipeline之间连接的桥梁,
每一个ChannelHandlerContext都有属于自己的上下文,
每一个ChannelHandlerContext上如果有AttributeMap都是绑定上下文的,
A的ChannelHandlerContext中的AttributeMap,B的ChannelHandlerContext是无法读取到的。
但是Channel上的AttributeMap是共享的,每一个ChannelHandler都能获取到。
使用
定义
public static final AttributeKey<NettyChannel> NETTY_CHANNEL_KEY = AttributeKey.valueOf("netty.channel");
示例这里的AttributeMap中存储NettyChannel
package com.lyncc.netty.attributeMap; import java.util.Date; public class NettyChannel { private String name; private Date createDate; public NettyChannel(String name,Date createDate) { this.name = name; this.createDate = createDate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } }
使用
@Override public void channelActive(ChannelHandlerContext ctx) { Attribute<NettyChannel> attr = ctx.attr(NETTY_CHANNEL_KEY); NettyChannel nChannel = attr.get(); if (nChannel == null) { NettyChannel newNChannel = new NettyChannel("HelloWorld0Client", new Date()); nChannel = attr.setIfAbsent(newNChannel); } else { System.out.println("attributeMap 中是有值的"); System.out.println(nChannel.getName() + "=======" + nChannel.getCreateDate()); } System.out.println("HelloWorldC0ientHandler Active"); ctx.fireChannelActive(); }
Channel的状态变换
被Bootstrap引导的NioSocketChannel在构造好之后就进入了open状态,之后通过把自己注册进EventLoop进入registered状态,接着连接服务器进入active状态。
查询状态的方法:
1. isOpen()
2. isRegistered()
3. isActive()
4. isWriteable()
本文参考:
http://blog.csdn.net/linuu/article/details/51502136
http://blog.csdn.net/zxhoo/article/details/17964353
- Netty权威指南 第2版学习笔记9——Channel,Unsafe和 AttributeMap
- Netty权威指南 第2版学习笔记3——Netty NIO开发指南
- Netty权威指南 第2版学习笔记5——分隔符和定长解码器的应用
- Netty权威指南 第2版学习笔记2——NIO入门
- Netty权威指南 第2版学习笔记7——MessagePack编解码及LengthFieldBasedFrameDecoder
- Netty权威指南 第2版学习笔记10——实现HTTP服务
- Netty权威指南 第2版学习笔记11——实现WebSocket
- Netty权威指南 第2版学习笔记1——Java的I/O演进之路
- Netty权威指南 第2版学习笔记4——TCP粘包/拆包问题的解决之道
- Netty权威指南 第2版学习笔记6——常见序列化与反序列化框架
- Netty权威指南 第2版学习笔记8——Google Protobuf编解码(未写)
- 《netty权威指南》学习笔记2
- Netty权威指南(第2版)
- Netty 权威指南笔记(六):Channel 解读
- Netty权威指南学习笔记1
- 《netty权威指南》学习笔记1
- netty权威指南 学习笔记http
- 《Netty权威指南》学习
- 华行编译文件Makefile
- composer安装yii时遇到token问题
- 设备像素比(devicePixelRatio)
- 一周总结 app换肤和夜间模式问题
- spring事务详解
- Netty权威指南 第2版学习笔记9——Channel,Unsafe和 AttributeMap
- easyui关闭所有tab
- struts2中<s:if>标签的使用
- JSP 自定义标签
- Android中的各种进程的介绍
- js元素and事件
- NodeJS 工程师必备的 8 个工具
- 京京_多标签页的显示
- 一致性hash算法