下面接着看下面这段代码
//Binder里面的代码
public void channelOpen(
ChannelHandlerContext ctx,
ChannelStateEvent evt) {
try {
evt.getChannel().getConfig().setPipelineFactory(getPipelineFactory());
// Split options into two categories: parent and child.
Map<String, Object> allOptions = getOptions();
Map<String, Object> parentOptions = new HashMap<String, Object>();
for (Entry<String, Object> e: allOptions.entrySet()) {
if (e.getKey().startsWith("child.")) {
childOptions.put(
e.getKey().substring(6),
e.getValue());
} else if (!e.getKey().equals("pipelineFactory")) {
parentOptions.put(e.getKey(), e.getValue());
}
}
// Apply parent options.
evt.getChannel().getConfig().setOptions(parentOptions);
} finally {
ctx.sendUpstream(evt);
}
//evt.getChannel().bind()这里开始调用绑定本地接口, 进入里面看下面的情况
boolean finished = futureQueue.offer(evt.getChannel().bind(localAddress));
assert finished;
}
public static ChannelFuture bind(Channel channel, SocketAddress localAddress) {
if (localAddress == null) {
throw new NullPointerException("localAddress");
}
ChannelFuture future = future(channel);
//像pipeline发送一个bound消息, 里面存储本地地址, 接着看里面的写法。
channel.getPipeline().sendDownstream(new DownstreamChannelStateEvent(
channel, future, ChannelState.BOUND, localAddress));
return future;
}
//DefaultPipeLine.java
public void sendDownstream(ChannelEvent e) {
DefaultChannelHandlerContext tail = getActualDownstreamContext(this.tail);
if (tail == null) {
try {
//getSink() 这个sink是在channel里面放入的NioServerSocketPipelineSink, 里面还放了NioWorker,嘿嘿
getSink().eventSunk(this, e);
return;
} catch (Throwable t) {
notifyHandlerException(e, t);
return;
}
}
sendDownstream(tail, e);
}
//NioServerSocketPipelineSink.java 进入这个里面
private void handleServerSocket(ChannelEvent e) {
if (!(e instanceof ChannelStateEvent)) {
return;
}
ChannelStateEvent event = (ChannelStateEvent) e;
NioServerSocketChannel channel =
(NioServerSocketChannel) event.getChannel();
ChannelFuture future = event.getFuture();
ChannelState state = event.getState();
Object value = event.getValue();
switch (state) {
case OPEN:
if (Boolean.FALSE.equals(value)) {
close(channel, future);
}
break;
case BOUND:
if (value != null) {
//进入这个方法里面, 进行接口的绑定
bind(channel, future, (SocketAddress) value);
} else {
close(channel, future);
}
break;
}
}
private void bind(
NioServerSocketChannel channel, ChannelFuture future,
SocketAddress localAddress) {
boolean bound = false;
boolean bossStarted = false;
try {
//socket绑定bind
channel.socket.socket().bind(localAddress, channel.getConfig().getBacklog());
bound = true;
future.setSuccess();
//触发bound事件
fireChannelBound(channel, channel.getLocalAddress());
Executor bossExecutor =
((NioServerSocketChannelFactory) channel.getFactory()).bossExecutor;
//它的作用是将bossExecutor 和Boss绑定在一起。
DeadLockProofWorker.start(
bossExecutor,
new ThreadRenamingRunnable(
//主要看new Boss()这个里面的实现
new Boss(channel),
"New I/O server boss #" + id + " (" + channel + ')'));
bossStarted = true;
} catch (Throwable t) {
future.setFailure(t);
fireExceptionCaught(channel, t);
} finally {
if (!bossStarted && bound) {
close(channel, future);
}
}
}
//Boss.java
Boss(NioServerSocketChannel channel) throws IOException {
//channel是netty封装的一成NioServerChannel
this.channel = channel;
//打开一个选择,nio里面的东西。 选择器
selector = Selector.open();
//标志
boolean registered = false;
try {
// channel.socket 是nio里面的NioServerChannel里面的东西, register注册accept事件, 一有客户连接上来进去在selector能找到。
channel.socket.register(selector, SelectionKey.OP_ACCEPT);
registered = true;
} finally {
if (!registered) {
closeSelector();
}
}
//嘿嘿, 记住这里把selector放进去了。
channel.selector = selector;
}
//上面的DeadLockProofWorker.start()有启动这个线程
public void run() {
final Thread currentThread = Thread.currentThread();
//这里使用锁, 来防止高并发
channel.shutdownLock.lock();
try {
for (;;) {
try {
if (selector.select(1000) > 0) {
selector.selectedKeys().clear();
}
//接收客户端socket, 当客户端有连入时,这里会记录
SocketChannel acceptedSocket = channel.socket.accept();
if (acceptedSocket != null) {
//注册接入进来的客户端 registerAcceptedChannel(acceptedSocket, currentThread);
}
} catch (SocketTimeoutException e) {
// Thrown every second to get ClosedChannelException
// raised.
} catch (CancelledKeyException e) {
// Raised by accept() when the server socket was closed.
} catch (ClosedSelectorException e) {
// Raised by accept() when the server socket was closed.
} catch (ClosedChannelException e) {
// Closed as requested.
break;
} catch (Throwable e) {
logger.warn(
"Failed to accept a connection.", e);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// Ignore
}
}
}
} finally {
channel.shutdownLock.unlock();
closeSelector();
}
}
private void registerAcceptedChannel(SocketChannel acceptedSocket, Thread currentThread) {
try {
ChannelPipeline pipeline =
//channel.getConfig()放入的 是我们自己重新的方法.这一段,所以里面的getPipeline()就把我们直接写的handler嵌入进来了。
/* bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new StringDecoder(), new StringEncoder(), new ServerHandler());
}
});*/ channel.getConfig().getPipelineFactory().getPipeline();
NioWorker worker = nextWorker();
//从这里进入
worker.register(new NioAcceptedSocketChannel(
channel.getFactory(), pipeline, channel,
NioServerSocketPipelineSink.this, acceptedSocket,
worker, currentThread), null);
} catch (Exception e) {
logger.warn(
"Failed to initialize an accepted socket.", e);
try {
acceptedSocket.close();
} catch (IOException e2) {
logger.warn(
"Failed to close a partially accepted socket.",
e2);
}
}
}
//NioWorker.java
void register(NioSocketChannel channel, ChannelFuture future) {
boolean server = !(channel instanceof NioClientSocketChannel);
//channel是和registerTask关联的, 没一个客户端连接都会绑定一个线程。
Runnable registerTask = new RegisterTask(channel, future, server);
//临时选择器
Selector selector;
synchronized (startStopLock) {
//注意这里, 这里只会执行一次if里面的代码
if (!started) {
// Open a selector if this worker didn't start yet.
try {
//选择器
this.selector = selector = Selector.open();
} catch (Throwable t) {
throw new ChannelException(
"Failed to create a selector.", t);
}
// Start the worker thread with the new Selector.
String threadName =
(server ? "New I/O server worker #"
: "New I/O client worker #") + bossId + '-' + id;
boolean success = false;
try {
DeadLockProofWorker.start(
executor, new ThreadRenamingRunnable(this, threadName));
success = true;
} finally {
if (!success) {
// Release the Selector if the execution fails.
try {
selector.close();
} catch (Throwable t) {
logger.warn("Failed to close a selector.", t);
}
this.selector = selector = null;
// The method will return to the caller at this point.
}
}
} else {
// Use the existing selector if this worker has been started.
selector = this.selector;
}
assert selector != null && selector.isOpen();
started = true;
//把注册的任务放入到 registerTaskQueue里面
boolean offered = registerTaskQueue.offer(registerTask);
assert offered;
}
if (wakenUp.compareAndSet(false, true)) {
selector.wakeup();
}
}
今天就暂时说到这里, 有什么不明白的。可以问我。