介绍:
ServerBootstrap是一个用来创建服务端Channel的工具类,创建出来的Channel用来接收进来的请求;只用来做面向连接的传输,像TCP/IP。说他是创建Channel的,那么是如何创建的呢?其实也是利用配置的ChannelFactory创建的,这个赋值是在Bootstrap里面做的。
类图:
ServerBootstrap.png关键方法介绍:
setFactory:
/**
* {@inheritDoc}
*
* @throws IllegalArgumentException
* if the specified {@code factory} is not a
* {@link ServerChannelFactory}
*/
@Override
public void setFactory(ChannelFactory factory) {
if (factory == null) {
throw new NullPointerException("factory");
}
if (!(factory instanceof ServerChannelFactory)) {
throw new IllegalArgumentException(
"factory must be a " +
ServerChannelFactory.class.getSimpleName() + ": " +
factory.getClass());
}
super.setFactory(factory);@1
}
@1:最终还是调用Bootstrap的setFactory方法。
bind:
public Channel bind(final SocketAddress localAddress) {
if (localAddress == null) {
throw new NullPointerException("localAddress");
}
final BlockingQueue<ChannelFuture> futureQueue =
new LinkedBlockingQueue<ChannelFuture>();@1
ChannelPipeline bossPipeline = pipeline();@2
bossPipeline.addLast("binder", new Binder(localAddress, futureQueue));@3
ChannelHandler parentHandler = getParentHandler();
if (parentHandler != null) {
bossPipeline.addLast("userHandler", parentHandler);
}
Channel channel = getFactory().newChannel(bossPipeline);@4
// Wait until the future is available.
ChannelFuture future = null;
do {
try {
future = futureQueue.poll(Integer.MAX_VALUE, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// Ignore
}
} while (future == null);
// Wait for the future.
future.awaitUninterruptibly();
if (!future.isSuccess()) {@5
future.getChannel().close().awaitUninterruptibly();
throw new ChannelException("Failed to bind to: " + localAddress, future.getCause());
}
return channel;
}
返回值:是一个用来接受客户端请求、绑定过地址的Channel。
@1:存放异步IO操作结果的队列。
@2:创建一个空的DefaultChannelPipeline。
@3:增加一个ChannelHandler(Binder)到pipeline上面。
@4:创建一个server-socket channel。
@5:当异步IO操作成功的完成的时候,会返回true。
channelOpen:
@Override
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);@1
}
boolean finished = futureQueue.offer(evt.getChannel().bind(localAddress));@2
assert finished;
}
@1:参数是代表着渠道状态改变的事件(基于事件)。
@2:发送一个绑定的请求到指定Channel的ChannelPipeline中的ChannelDownstreamHandler。
总结:
上面是针对ServerBootstrap简单的一点分析,偏向于表面,大的结构,没有深入到具体的细节里面。无论要掌握何种知识,都要由浅入深,不要一上来就抓住某个点不放。循序渐进,有了坚持和热情,就相当于已经成功了。
网友评论