本次将搭建一个最简单的Hello Netty服务器,并且通过这个简单的示例了解了Channel的生命周期。最后将基于Netty搭建一个Websocket网页聊天小程序,可以使用户在Web浏览器或者移动端浏览器进行消息的收发,来深入体会一下使用Netty编码NIO服务器是多么便捷。
Hello Netty服务器
- 构建一对主从线程组
- 定义服务器启动类
- 为服务器设置Channel
- 设置处理从线程池的助手类初始化器
- 监听启动和关闭服务器
1、构建主从线程组与服务启动类
首先新建一个Maven工程,引入Netty的依赖,我引入的依赖如下:
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.50.Final</version>
</dependency>
</dependencies>
![mark](https://i-blog.csdnimg.cn/blog_migrate/637e44de58e204b2d2b7b3001bbcc458.png)
2、设置Channel初始化器
每一个channel由多个handler共同组成管道(pipeline)
![mark](https://i-blog.csdnimg.cn/blog_migrate/298386b6af4ee2df555da1345cd4a1fc.png)
![mark](https://i-blog.csdnimg.cn/blog_migrate/b8392d0a194fa9aa0c5117b6713958da.png)
3、开始编写自定义的助手类
![mark](https://i-blog.csdnimg.cn/blog_migrate/76d85d9f2e8d27eb8de44a528c285284.png)
然后接下来启动服务器,通过Postman访问一下http://localhost:8080
得到如下结果:
![mark](https://i-blog.csdnimg.cn/blog_migrate/1090551561918e39d36f481c7aa668ba.png)
如果直接在浏览器端访问的话会打印两次客户端远程地址,因为浏览器默认还访问了http://localhost:8080/favicon.ico
,或者使用在Linux环境下使用curl进行测试也是可以的。
探究Channel生命周期
我们通过重写下图所示的方法来研究一下Channel的生命周期(IDEA快捷键 Ctrl + O):
![mark](https://i-blog.csdnimg.cn/blog_migrate/3394733c3206f848db4af8d4b6730022.png)
重写完成之后的CustomHandler如下:
public class CustomHandler extends SimpleChannelInboundHandler<HttpObject> {
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg) throws Exception {
// 获取Channel
Channel channel = ctx.channel();
if(msg instanceof HttpRequest) {
// 显示客户端的远程地址
System.out.println(channel.remoteAddress());
// 数据Copy至缓冲区(定义发送的数据消息)
ByteBuf content = Unpooled.copiedBuffer("<h1>Hello Netty</h1>", CharsetUtil.UTF_8);
// 构建一个Http Response
FullHttpResponse response = new DefaultFullHttpResponse(
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, content);
// 为响应增加一个数据类型和长度
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text.plain");
response.headers().set(HttpHeaderNames.CONTENT_LENGTH, content.readableBytes());
// 把响应刷到客户端
ctx.writeAndFlush(response);
}
}
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
System.out.println("Channel-注册");
super.channelR