Article From:https://www.cnblogs.com/heroinss/p/9968988.html

Reprinted from https://blog.csdn.net/zxhoo/article/details/17964353

 

 

ChannelInheritance Hierarchy Graph
When analyzing the three states mentioned above, I will look at the code of some classes in the Channel inheritance hierarchy. For ease of reference, I drew a (not too strict) UML class diagram, as follows:

 

openstate
Starting with the isOpen () method, the isOpen () method is implemented in the AbstractNioChannel Abstract class. Here is the key code for this class:

public abstract class AbstractNioChannel extends AbstractChannel {

private final SelectableChannel ch;

    @Override
    public boolean isOpen() {
        return ch.isOpen();
    }

}
As you can see, whether Netty Channel is open depends on whether Java Selectable Channel is open. In other words, just find out when Netty opens the Selectable Channel.To know when Channel has reached the open state. Starting with Bootstrap’s connect () method, you can find out the answer.
Bootstrap.connect(String inetHost, int inetPort)
-> Bootstrap.doConnect(final SocketAddress remoteAddress, final SocketAddress localAddress)
-> AbstractBootstrap.initAndRegister()
-> BootstrapChannelFactory.newChannel()
-> NioSocketChannel()
-> NioSocketChannel.newSocket()
-> SocketChannel.open()
Focus on the initAndRegister () method:
// AbstractBootstrap.java
final ChannelFuture initAndRegister() {
final Channel channel = channelFactory().newChannel();
try {
init(channel);
} catch (Throwable t) {
channel.unsafe().closeForcibly();
return channel.newFailedFuture(t);
}

ChannelPromise regPromise = channel.newPromise();
group().register(channel, regPromise);

        return regPromise;
    }
initAndRegister()The method first creates the Channel instance (Channel is already in the open state at this time) and then registers it in the group, so you probably know that Channel is in the registered state after opening, as shown in the following figure:

registeredstate
To prove the above guess, let’s look at the code from the NioEventLoopGroup. register () method. NioEventLoopGroup does not implement the register () method. The real implementation is its superclass MultiIn threadEventLoop Group:

// MultithreadEventLoopGroup.java
@Override
public ChannelFuture register(Channel channel, ChannelPromise promise) {
return next().register(channel, promise);
}
According to this article, the next () method returns a NioEventLoop. Looking at the code, you know that the register () method is implemented in the superclass of NioEventLoop, SingleThreadEventLoop:
// SingleThreadEventLoop.java
@Override
public ChannelFuture register(final Channel channel, final ChannelPromise promise) {

channel.unsafe().register(this, promise);
return promise;
}
Well, keep looking at the code until you know that the AbstractChannel. AbstractUnsafe. register () method is called, which in turn calls the AbstractUnsafe. register0 () method, in regIn the ister0 () method, the registered field is set to true. AbstractChannel’s isRegistered () method, on the other hand, uses this field to determine whether it is a registered state:
// AbstractChannel.java
@Override
public boolean isRegistered() {
return registered;
}
That is to say, the above guess is correct. Channel enters open state first, and then registers itself into registered state by registering itself to group.

activestate
Or first look at how the isActive () method is implemented (in NioSocket Channel):

// NioSocketChannel.java
@Override
public boolean isActive() {
SocketChannel ch = javaChannel();
return ch.isOpen() && ch.isConnected();
}
That is to say, the active state of NioSocket Channel depends on the state of Socket Channel. According to the previous analysis, after the NioSocketChannel constructor is executed, SocketChannel hasIn the open state, the next step is to see when SocketChannel’s connect () method is called. Back to the doConnect () method of the Bootstrap class:
Bootstrap.connect(String inetHost, int inetPort)
-> Bootstrap.doConnect(final SocketAddress remoteAddress, final SocketAddress localAddress)
-> AbstractBootstrap.initAndRegister()
Bootstrap.doConnect0(…)
-> Channel.connect(SocketAddress remoteAddress, ChannelPromise promise
doConnect()The method calls the doConnect0 () method after initAndRegister (), and the doConnect0 () method calls the Channel’s connect () method. There’s conn in AbstractChannelThe implementation of ECT () method:
// AbstractChannel.java
@Override
public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
return pipeline.connect(remoteAddress, promise);
}
That is to say, connect is actually handed over to pipeline as an event, and it’s an outbound event. Look at Default Channel Pipeline:
// DefaultChannelPipeline.java
@Override
public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
return tail.connect(remoteAddress, promise);
}
tailDefault ChannelHandlerContext instance:
// DefaultChannelHandlerContext.java
@Override
public ChannelFuture connect(SocketAddress remoteAddress, ChannelPromise promise) {
return connect(remoteAddress, null, promise);
}

@Override
public ChannelFuture connect(final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {

final DefaultChannelHandlerContext next = findContextOutbound();
EventExecutor executor = next.executor();
if (executor.inEventLoop()) {
next.invokeConnect(remoteAddress, localAddress, promise);
} else {
safeExecute(executor, new Runnable() {
@Override
public void run() {
next.invokeConnect(remoteAddress, localAddress, promise);
}
}, promise, null);
}

return promise;
}

    private void invokeConnect(SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) {
        try {
            ((ChannelOutboundHandler) handler).connect(this, remoteAddress, localAddress, promise);
        } catch (Throwable t) {
            notifyOutboundHandlerException(t, promise);
        }
    }
The three parametric versions of the connect () method look complex, but there are only two things to do: first, find the first context of the outbound type along the pipeline, and then call the invokeConnect of the context.Method. Then context calls the connection () method of handler, and there must be an outbound type context / handler in the pipeline. This context is the head, and the corresponding HAndler is the internal class HeadHandler:
// DefaultChannelPipeline.java
static final class HeadHandler implements ChannelOutboundHandler {
protected final Unsafe unsafe;

    protected HeadHandler(Unsafe unsafe) {
        this.unsafe = unsafe;
    }

@Override
    public void connect(ChannelHandlerContext ctx, SocketAddress remoteAddress, SocketAddress localAddress, ChannelPromise promise) throws Exception {
        unsafe.connect(remoteAddress, localAddress, promise);
    }

}
HeadHandlerIt just calls unsafe’s connect () method, which is passed in from the constructor:
public DefaultChannelPipeline(AbstractChannel channel) {

HeadHandler headHandler = new HeadHandler(channel.unsafe());
head = new DefaultChannelHandlerContext(this, null, generateName(headHandler), headHandler);

}
Unsafe.connect()Method is implemented in AbstractNioChannel. AbstractNioUnsafe, which calls the AbstractNioChannel. doConnect () method. The doConnect () method ends up at NIt is realized in ioSocket Channel:
// NioSocketChannel.java
@Override
protected boolean doConnect(SocketAddress remoteAddress, SocketAddress localAddress) throws Exception {
if (localAddress != null) {
javaChannel().socket().bind(localAddress);
}

boolean success = false;
try {
boolean connected = javaChannel().connect(remoteAddress);
if (!connected) {
selectionKey().interestOps(SelectionKey.OP_CONNECT);
}
success = true;
return connected;
} finally {
if (!success) {
doClose();
}
}
}
conclusion
Code analysis is complex, but the conclusion is simple: the Nosocket Channel, guided by Bootstrap, goes into open state after being constructed, registers itself into EventLoop into registered state, and then connects.The server is in active state.

 

———————
Author: zxh0
Source: CSDN
Original: https://blog.csdn.net/zxhoo/article/details/17964353
Copyright Statement: This article is the original article of the blogger. Please attach a link to the blog article for reprinting.

Link of this Article: Status of nioServer Channel

Leave a Reply

Your email address will not be published. Required fields are marked *