0
点赞
收藏
分享

微信扫一扫

Netty DiscardServer 服务端启动 #yyds干货盘点#

netty-example 最简单的demo 服务端启动


服务端启动 DEMO 代码

public final class DiscardClient {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", "8009"));

public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
sslCtx = null;
}

EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc()));
}
p.addLast(new DiscardServerHandler());
}
});

// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(PORT).sync();

// Wait until the server socket is closed.
// In this example, this does not happen, but you can do that to gracefully
// shut down your server.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}

/**
* Handles a server-side channel.
*/
public class DiscardServerHandler extends SimpleChannelInboundHandler<Object> {

@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
// discard
}

@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
// Close the connection when an exception is raised.
cause.printStackTrace();
ctx.close();
}
}


上面是服务端启动的简单代码,下面描述下15到35行代码发生了什么


发生了啥

new NioEventLoopGroup()

  • 初始化了 EventExecutor[] children 为 CPU核心数量 * 2个 NioEventLoop实例,
  • 默认每个NioEventLoop包含 一个 线程工厂(DefaultThreadFactory),创建出来的线程类型为:FastThreadLocalThread
  • 默认初始化了选择器为 SelectorProvider.provider()
  • 选择器工作策略。默认是 DefaultSelectStrategyFactory.INSTANCE
  • 默认线程池拒绝策略,RejectedExecutionHandlers.reject()
  • 默认初始化了 EventExecutorChooser chooser 为 PowerOfTwoEventExecutorChooser 
  • 给每一个 NioEventLoop 增加正常关闭的监听


new ServerBootstrap();

.group:设置group和childGroup

.channel:设置服务端channel的实例类型 ,方面后续bind时候反射创建NioServerSocketChannel实例

.handler:设置了客户端管道初始化handler,初始化了 ServerBootstrap 继承 AbstractBootstrap 中的 handler

.childHandler:设置了childHandler,初始化了ServerBootstrap 中的 childHandler

.bind:绑定SocketAddress(服务端的地址)

  • 反射创建NioServerSocketChannel实例
  • SelectorProvider.provider()构建出对应的ServerSocketChannelImpl
  • 分配id
  • 创建对应的unsafe实例
  • 初始化pipeline
  • 固定头节点
  • 固定尾节点
  • 设置监听事件 readInterestOp 为 SelectionKey.OP_ACCEPT
  • 设置为非阻塞
  • 配置 NioServerSocketChannelConfig
  • 设置缓冲区内存分配器 rcvBufAllocator 为 ServerChannelRecvByteBufAllocator
  • init
  • 设置用户设置的channelOptions和attributes
  • 初始化pipeline
  • 向添加最后添加一个ChannelInitializer
  • 第一步设置group中,的EventExecutorChooser chooser 选择一个 EventLoop
  • EventLoop 创建一个 DefaultChannelPromise
  • promise.channel().unsafe().register(this, promise);
  • 通过promise然后拿到channel然后拿到unsafe实例然后
  • register发生了什么
  • 将NioEventLoop 保存到serverChannel
  • 向刚注册的NioEventLoop提交register,将NioServerSocketChannel注册到group中
  • 返回注册任务关联的ChannelFuture
  • 向ChannelFuture添加addListener

.sync():主线程一直等待,直到成功/失败 才继续执行




举报

相关推荐

0 条评论