所有 Netty 服务端的启动类都可以采用如下代码结构进行开发。简单梳理一下流程:首先创建引导器;然后配置线程模型,通过引导器绑定业务逻辑处理器,并配置一些网络参数;最后绑定端口,就可以完成服务器的启动了。
public class HttpServer {
public void start(int port) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast("codec", new HttpServerCodec()) // HTTP 编解码
.addLast("compressor", new HttpContentCompressor()) // HttpContent 压缩
.addLast("aggregator", new HttpObjectAggregator(65536)) // HTTP 消息聚合
.addLast("handler", new HttpServerHandler()); // 自定义业务逻辑处理器
}
})
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind().sync();
System.out.println("Http Server started, Listening on " + port);
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
new HttpServer().start(8088);
}
}
public class HttpServerHandler extends SimpleChannelInboundHandler{ @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) { String content = String.format("Receive http request, uri: %s, method: %s, content: %s%n", msg.uri(), msg.method(), msg.content().toString(CharsetUtil.UTF_8)); FullHttpResponse response = new DefaultFullHttpResponse( HttpVersion.HTTP_1_1, HttpResponseStatus.OK, Unpooled.wrappedBuffer(content.getBytes())); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } }
Q1:服务端的Socket在哪里初始化?
Q2:在哪里accpet连接?
1.bind() ----用户代码入口
2.initAndRegister() ---- 初始化并注册
3.new Channel() -----创建服务端Channel
NioServerSocketChannel:
反射创建服务端Channel
1.new Socket() ----通过jdk来创建底层jdk channel
2.NioServerSocketChannelConfig ----- tcp参数配置类
3.AbstractNioChannel()
configureBlocking(false) ------ 阻塞模式
AbstractChannel() -----创建id,unsafe,pipeline
init() — 初始化入口
set ChannelOptions, ChannelAttrs
set ChildOptions,ChildAttrs
config handler 配置服务端pipeline
add ServerBootstrapAcceptor 添加连接器
AbstractChannel.register(channel)[入口]
this.eventLoop = eventLoop[绑定线程]
register0()[实际注册]
doRegister()[调用jdk底层注册]
invokeHandlerAddedIfNeeded()
fireChannelRegistered[传播时间]
AbstractUnsafe.bind()[入口]
doBind()
javaChannel().bind()[jdk底层绑定]
pipeline.fireChannelActive()[传播事件]
HeadContext.readIfIsAutoRead()



