Netty websocket服务端心跳检测小计
最近在使用netty搭建了websocket服务器,在做心跳检测的时候遇到了一些问题,现在做一个简单的记录
在一开始的时候,查阅文档,采用的是netty提供的心跳检测方法IdleStateHandler
阅读文档可以看到,这个handler接收4个参数,如图1,分别是读,写,读写,时间类型4种,即三种状态检测时间间隔
按照这个方法使用并且配置好了之后,然后在SimpleChannelInboundHandler的实现类中重写userEventTriggered这个方法,检测整个长连接通讯过程中是否存在读,写空闲状态,通过日志,可以看到确实可以检测到空闲状态,但是这个时候发现一个问题,在客户端持续发心跳ping包的时候,在userEventTriggered这个方法中并不能监控到,然后开始查资料,发现在websocket里面,对消息进行了分类,从大的方向上来说,分成了消息帧与控制帧,其中SimpleChannelInboundHandler这个handler中处理的都是消息帧,主要包括TextWebSocketFrame(文本消息),FullHttpRequest(http消息,在握手的时候,协议还未升级到websocket的时候触发),BinaryWebSocketFrame(字节消息),然后还有一个WebSocketServerProtocolHandler这个handler,用来处理控制帧,主要包括PingWebSocketFrame(ping消息),PongWebSocketFrame(pong消息),CloseWebSocketFrame(断开消息)
然后我从WebSocketServerProtocolHandler源码中发现,在这个handler中有一个decode方法,该方法下面实现了对CloseWebSocketFrame的消息处理,然后在这个的super方法中看到了对ping,pong消息的处理,于是我新建了一个handler继承WebSocketServerProtocolHandler,并且重写了decode方法,在这里面对ping,pong消息进行了监听,然后通过日志,果然可以完美监听到了客户端发过来的心跳包
总结:通过IdleStateHandler检测的是消息帧,如果是实现自定义消息类型的心跳包可以通过该方法检测实现,如果是检测控制帧中的ping,pong心跳包,则需要通过WebSocketServerProtocolHandler这个handler实现