几十行代码基于Netty搭建一个 HTTP Server( 四 )
简单解析一下服务端的创建过程具体是怎样的!
1.创建了两个 NioEventLoopGroup
对象实例:bossGroup
和 workerGroup
。
bossGroup
: 用于处理客户端的 TCP 连接请求 。workerGroup
: 负责每一条连接的具体读写数据的处理逻辑 , 真正负责 I/O 读写操作 , 交由对应的 Handler 处理 。
NioEventLoopGroup
类的无参构造函数设置线程数量的默认值就是 CPU 核心数 *2。2.创建一个服务端启动引导/辅助类:
ServerBootstrap
, 这个类将引导我们进行服务端的启动工作 。3.通过
.group()
方法给引导类 ServerBootstrap
配置两大线程组 , 确定了线程模型 。4.通过
channel()
方法给引导类 ServerBootstrap
指定了 IO 模型为NIO
NioServerSocketChannel
:指定服务端的 IO 模型为 NIO , 与 BIO 编程模型中的ServerSocket
对应NioSocketChannel
: 指定客户端的 IO 模型为 NIO ,与 BIO 编程模型中的Socket
对应
.childHandler()
给引导类创建一个ChannelInitializer
, 然后指定了服务端消息的业务处理逻辑也就是自定义的ChannelHandler
对象6.调用
ServerBootstrap
类的 bind()
方法绑定端口。//bind()是异步的 , 但是 , 你可以通过 sync()方法将其变为同步 。 ChannelFuture f = b.bind(port).sync();
自定义服务端 ChannelHandler 处理 HTTP 请求我们继承SimpleChannelInboundHandler
,并重写下面 3 个方法:channelRead()
:服务端接收并处理客户端发送的 HTTP 请求调用的方法 。exceptionCaught()
:处理客户端发送的 HTTP 请求发生异常的时候被调用 。channelReadComplete()
: 服务端消费完客户端发送的 HTTP 请求之后调用的方法 。
FullHttpRequest
。 我们可以把 FullHttpRequest
对象看作是 HTTP 请求报文的 Java 对象的表现形式 。@Slf4jpublic class HttpServerHandler extends SimpleChannelInboundHandler {private static final String FAVICON_ICO = "/favicon.ico";private static final AsciiString CONNECTION = AsciiString.cached("Connection");private static final AsciiString KEEP_ALIVE = AsciiString.cached("keep-alive");private static final AsciiString CONTENT_TYPE = AsciiString.cached("Content-Type");private static final AsciiString CONTENT_LENGTH = AsciiString.cached("Content-Length");@Overrideprotected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest) {log.info("Handle http request:{}", fullHttpRequest);String uri = fullHttpRequest.uri();if (uri.equals(FAVICON_ICO)) {return;}RequestHandler requestHandler = RequestHandlerFactory.create(fullHttpRequest.method());Object result;FullHttpResponse response;try {result = requestHandler.handle(fullHttpRequest);String responseHtml = "" + result + "";byte[] responseBytes = responseHtml.getBytes(StandardCharsets.UTF_8);response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(responseBytes));response.headers().set(CONTENT_TYPE, "text/html; charset=utf-8");response.headers().setInt(CONTENT_LENGTH, response.content().readableBytes());} catch (IllegalArgumentException e) {e.printStackTrace();String responseHtml = "" + e.toString() + "";byte[] responseBytes = responseHtml.getBytes(StandardCharsets.UTF_8);response = new DefaultFullHttpResponse(HTTP_1_1, INTERNAL_SERVER_ERROR, Unpooled.wrappedBuffer(responseBytes));response.headers().set(CONTENT_TYPE, "text/html; charset=utf-8");}boolean keepAlive = HttpUtil.isKeepAlive(fullHttpRequest);if (!keepAlive) {ctx.write(response).addListener(ChannelFutureListener.CLOSE);} else {response.headers().set(CONNECTION, KEEP_ALIVE);ctx.write(response);}}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {cause.printStackTrace();ctx.close();}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx) {ctx.flush();}}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 华硕基于WRX80的主板现身 为AMD Ryzen Threadripper Pro打造
- 锐龙5000微代码更新:超频更稳、X570无需风扇
- 微软新版电子邮件客户端截图曝光:基于网页端Outlook
- 小米MIUI代码泄露新机:或edmi K40
- 曝光 | 小鹏或春节前推送NGP更新,基于高精地图可自动变道
- 用Python制作图片验证码,这三行代码完事儿
- 基于Spring+Angular9+MySQL开发平台
- 微软称SolarWinds黑客攻击波及公司内部的源代码存储库
- 整合零代码+AI+云原生技术,「速优云」布局智慧教培和智慧社区
- 终于可以自定义喇叭声:你的特斯拉可以“放屁”吓唬人了