最近用Netty遇到的坑

最近诸事不顺,感觉状态有点问题!本来以为简单的Netty已经用得比较熟练了,结果这星期又遇到了一堆坑!

赶紧写篇博客记录一下,端正自己的学习态度。

 

一、再次强调keep-alive的问题

问题最早出现在这里:

http://www.xie4ever.com/2017/07/22/%E4%BD%BF%E7%94%A8netty%E5%AE%9E%E7%8E%B0%E7%AE%80%E5%8D%95%E7%9A%84http%E6%9C%8D%E5%8A%A1%E5%99%A8/

如果来自客户端的http请求带有keep-alive,就说明客户端希望能够复用链接传输内容,那么Netty不应该主动关闭链接。

具体逻辑写成这样:

可以看见,如果有keep-alive,ctx在输出内容后就不会加上ChannelFutureListener.CLOSE的Future,就算内容传输完成,Netty依然会保持链接。

那么问题来了:现在的浏览器大多采用HTTP1.1的标准,给出的任何http请求都会带上keep-alive。Netty服务端要传输的就那么多东西,传完了也不会关闭链接。因为链接还在保持,所以浏览器一直处于读取状态,一直转圈圈,就会对用户产生误导:“怎么我的页面还没加载完?”

对此,我们一般都会在Initializer中加个名为ReadTimeoutHandler的Handler,可以通过构造方法来加超时限制:

只要超时,就自动断开链接。

但是问题又来了:如果真的有很多东西要传,我又无视keep-alive提早断开了链接,岂不是传到一半就中断了?我的页面要怎么渲染…

到这里为止就是我没搞懂的地方了…如果对链接复用的要求不高,干脆无视keep-alive,传完就close了事。

二、handler中不能写全局变量

问题最早出现在这里:

http://www.xie4ever.com/2017/12/08/%E5%A6%82%E4%BD%95%E9%80%9A%E8%BF%87%E5%8D%8F%E8%AE%AEid%E6%89%BE%E5%88%B0%EF%BC%88%E8%B0%83%E7%94%A8%EF%BC%89%E6%96%B9%E6%B3%95%E5%85%A5%E5%8F%A3/

如果这样写:

HttpHelloWorldServerHandler.java

这里涉及Netty的实现原理。个人认为:Netty每处理一次请求,都会创建一个新的HttpHelloWorldServerHandler对象,cache对象当然也是新的,只能作用于当前的请求,无法起到全局缓存的效果。

还是要老老实实地写个单例模式。 // 这里加上代码

三、解析get和post的请求参数

参考:https://gist.github.com/wanghongfei/7c6a215f89e64d1c8863

画风差不多是这样:

 

禁止favicon.ico。

sb写的url。