Netty3 源码分析 - AbstractChannel
来源:互联网 发布:淘宝美工招聘网 编辑:程序博客网 时间:2024/05/22 07:00
Netty3 源码分析 - AbstractChannel
AbstractChannel 是Channel的部分实现,维护了一个通道相关的资源,如channel id, pipeline等;而且实现了对该套接字的IO操作,以及设置interestOps;这里还没有牵扯到底层的细节,只是这个框架的结构。(Channels中的具体实现有待分析)
源码能说明一切:
/**
* A skeletal Channel implementation.
*/
public abstract class AbstractChannel implements
org.jboss.netty.channel.Channel {
static final ConcurrentMap<Integer, Channel> allChannels = new ConcurrentHashMap<Integer, Channel>();
private static final Random random = new Random();
private static Integer allocateId(Channel channel) {
Integer id = random .nextInt();
for (;;) {
// 循环直到得到一个唯一的ID.
// It should be found in one loop practically.
if (allChannels .putIfAbsent(id, channel) == null ) {
// Successfully acquired.
return id;
} else {
// Taken by other channel at almost the same moment.
id = id.intValue() + 1;
}
}
}
private final Integer id ;
private final Channel parent ; //
private final ChannelFactory factory ;
private final ChannelPipeline pipeline ;
//
private final ChannelFuture succeededFuture = new SucceededChannelFuture(
this );
private final ChannelCloseFuture closeFuture = new ChannelCloseFuture();
private volatile int interestOps = OP_READ;
/** Cache for the string representation of this channel */
private boolean strValConnected ;
private String strVal;
private volatile Object attachment ;
/**
* 创建实例,注意各个参数的含义,特别是ChannelSink
*
* @param parent
* the parent of this channel. {@code null} if there's no parent.
* @param factory
* the factory which created this channel
* @param pipeline
* the pipeline which is going to be attached to this channel
* @param sink
* the sink which will receive downstream events from the
* pipeline and send upstream events to the pipeline
*/
protected AbstractChannel(Channel parent, ChannelFactory factory,
ChannelPipeline pipeline, ChannelSink sink) {
this .parent = parent;
this .factory = factory;
this .pipeline = pipeline;
id = allocateId( this);
pipeline.attach( this , sink);
}
// (Internal use only) Creates a new temporary instance with the specified
// ID.
protected AbstractChannel(Integer id, Channel parent,
ChannelFactory factory, ChannelPipeline pipeline, ChannelSink sink) {
this .id = id;
this .parent = parent;
this .factory = factory;
this .pipeline = pipeline;
pipeline.attach( this , sink);
}
public final Integer getId() {
return id ;
}
public Channel getParent() {
return parent ;
}
public ChannelFactory getFactory() {
return factory ;
}
public ChannelPipeline getPipeline() {
return pipeline ;
}
/**
* Returns the cached SucceededChannelFuture instance.
*/
protected ChannelFuture getSucceededFuture() {
return succeededFuture ;
}
/**
* Returns the FailedChannelFuture whose cause is an
* UnsupportedOperationException.
*/
protected ChannelFuture getUnsupportedOperationFuture() {
return new FailedChannelFuture( this,
new UnsupportedOperationException());
}
/**
* Returns the ID of this channel.
*/
@Override
public final int hashCode() {
return id ;
}
// 引用相等
@Override
public final boolean equals(Object o) {
return this == o;
}
// 用ID来比较
public final int compareTo(Channel o) {
return getId().compareTo(o.getId());
}
public boolean isOpen() {
return !closeFuture .isDone();
}
/**
* Marks this channel as closed. This method is intended to be called by an
* internal component - please do not call it unless you know what you are
* doing.
*
* @return {@code true} if and only if this channel was not marked as closed
* yet
*/
protected boolean setClosed() {
// Deallocate the current channel's ID from allChannels so that other
// new channels can use it.
allChannels .remove(id );
return closeFuture .setClosed();
}
// 下面都是调用辅助函数来完成套接字的基本操作逻辑
public ChannelFuture bind(SocketAddress localAddress) {
return Channels.bind( this , localAddress);
}
public ChannelFuture unbind() {
return Channels.unbind( this );
}
public ChannelFuture close() {
ChannelFuture returnedCloseFuture = Channels.close( this);
assert closeFuture == returnedCloseFuture;
return closeFuture ;
}
public ChannelFuture getCloseFuture() {
return closeFuture ;
}
public ChannelFuture connect(SocketAddress remoteAddress) {
return Channels.connect( this , remoteAddress);
}
public ChannelFuture disconnect() {
return Channels.disconnect( this );
}
public int getInterestOps() {
return interestOps ;
}
public ChannelFuture setInterestOps( int interestOps) {
return Channels.setInterestOps( this , interestOps);
}
/**
* Sets the interestOps property of this channel immediately. This method is
* intended to be called by an internal component - please do not call it
* unless you know what you are doing. 直接改变的成员变量,而不是通过发送请求码到最后一个handler
*/
protected void setInterestOpsNow( int interestOps) {
this .interestOps = interestOps;
}
public boolean isReadable() {
return (getInterestOps() & OP_READ) != 0;
}
public boolean isWritable() {
return (getInterestOps() & OP_WRITE) == 0;
}
public ChannelFuture setReadable( boolean readable) {
if (readable) {
return setInterestOps(getInterestOps() | OP_READ );
} else {
return setInterestOps(getInterestOps() & ~OP_READ );
}
}
public ChannelFuture write(Object message) {
return Channels.write( this , message);
}
public ChannelFuture write(Object message, SocketAddress remoteAddress) {
return Channels.write( this , message, remoteAddress);
}
public Object getAttachment() {
return attachment ;
}
public void setAttachment(Object attachment) {
this .attachment = attachment;
}
/**
* Returns the String representation of this channel. The returned string
* contains the ID, local address, and remote address of this channel for
* easier identification.
*/
@Override
public String toString() {
boolean connected = isConnected();
if (strValConnected == connected && strVal != null ) {
return strVal ;
}
StringBuilder buf = new StringBuilder(128);
buf.append( "[id: 0x" );
buf.append(getIdString());
SocketAddress localAddress = getLocalAddress();
SocketAddress remoteAddress = getRemoteAddress();
if (remoteAddress != null) {
buf.append( ", " );
if (getParent() == null) {
buf.append(localAddress);
buf.append(connected ? " => " : " :> ");
buf.append(remoteAddress);
} else {
buf.append(remoteAddress);
buf.append(connected ? " => " : " :> ");
buf.append(localAddress);
}
} else if (localAddress != null) {
buf.append( ", " );
buf.append(localAddress);
}
buf.append( ']');
String strVal = buf.toString();
this .strVal = strVal;
strValConnected = connected;
return strVal;
}
private String getIdString() {
String answer = Integer.toHexString( id.intValue());
switch (answer.length()) {
case 0:
answer = "00000000" ;
break ;
case 1:
answer = "0000000" + answer;
break ;
case 2:
answer = "000000" + answer;
break ;
case 3:
answer = "00000" + answer;
break ;
case 4:
answer = "0000" + answer;
break ;
case 5:
answer = "000" + answer;
break ;
case 6:
answer = "00" + answer;
break ;
case 7:
answer = '0' + answer;
break ;
}
return answer;
}
private final class ChannelCloseFuture extends DefaultChannelFuture {
public ChannelCloseFuture() {
super (AbstractChannel. this, false);
}
@Override
public boolean setSuccess() {
// User is not supposed to call this method - ignore silently.
return false ;
}
@Override
public boolean setFailure(Throwable cause) {
// User is not supposed to call this method - ignore silently.
return false ;
}
boolean setClosed() {
return super .setSuccess();
}
}
}
0 0
- Netty3 源码分析 - AbstractChannel
- Netty3 源码分析 - Channel
- Netty3 源码分析 - ChannelHandler
- Netty3 源码分析 - ChannelHandlerContext
- Netty3 源码分析 - ChannelEvent
- Netty3 源码分析 - ChannelState
- Netty3 源码分析 - ChannelStateEvent
- Netty3 源码分析 - OioClientSocketChannelFactory
- Netty3 源码分析 - ClientBootstrap
- Netty3 源码分析 - ChannelPipeline
- Netty3 源码分析 - ChannelFuture
- Netty3 源码分析 - ChannelUpstreamHandler
- netty3 源码分析解
- netty3.2.3源码分析--ServerBootstrap启动分析
- netty3.2.3源码分析-ClientBootstrap启动分析
- netty3.2.3源码分析--ServerBootstrap启动分析
- netty3.2.3源码分析-ClientBootstrap启动分析
- netty3.2.3源码分析--服务器端读数据分析
- java使用poi导出Excel(Excel为双标题)
- 黑马程序员—学习java基础3日记
- cocos2d-x基本知识点(2)
- 1.js标签解析
- mysql ERROR 1045 (28000): Access denied for user解决方法
- Netty3 源码分析 - AbstractChannel
- 【从源码看Android】04 Android dalvik虚拟机Thread的底层实现
- Java 注意事项
- MYSQL存储过程实例
- iOS开发中生成推送的pem文件
- Mipmap
- 想起以前面过的一道题目
- C/C++的类型安全
- fdfd