什么是心跳检测
心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。
在WebSocket中即判断套接字是否已经与服务器断开,无法使用,此时要清理服务器的该套接字进程以免浪费资源。
心跳包就是客户端定时发送简单的信息给服务器端告诉它还在正常运行。
比如针对客户端每个连接,服务器都会接收并存入一个容器进行统一管理。
客户端的正常结束,服务器会自动清理。
但某些特殊情况下,服务器无法识别。比如打开飞行模式后,关闭客户端,关闭飞行模式,重新打开客户端,
此时容器中并没有清理客户端,而此时又创建了一个客户端连接。
首先创建一个handler,实现心跳。仅检测读写空闲
import io.netty.channel.*;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
* @Author Sakura
* @Date 5/8/2019
* 用于检测channel心跳的handler
public class HeartBeatHandler extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
//判断evt是否是IdleStateEvent(用于触发用户事件,包含读空闲/写空闲/读写空闲)
if(evt instanceof IdleState){
IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
if(idleStateEvent.state() == IdleState.READER_IDLE){
System.out.println("进入读空闲...");
}else if(idleStateEvent.state() == IdleState.WRITER_IDLE){
System.out.println("进入写空闲...");
}else if(idleStateEvent.state() == IdleState.ALL_IDLE){
System.out.println("进入读写空闲...");
Channel channel = ctx.channel();
//关闭无用channel,避免浪费资源
channel.close();
后在初始化器中添加handler
package com.imooc.netty;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;
* @Author Sakura
* @Date 5/8/2019
public class WSServerInitializer extends ChannelInitializer {
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
//=============================增加心跳支持============================
//对客户端,如果在60秒内没有向服务端发送心跳,就主动断开
//三个参数分别为读/写/读写的空闲,我们只针对读写空闲检测
pipeline.addLast(new IdleStateHandler(2,4,60));
pipeline.addLast(new HeartBeatHandler());
初始化器是在ServerBootstrap里启动的
package com.imooc.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
* @Author Sakura
* @Date 5/8/2019
@Component
public class WSServer {
public static class SingletionWSServer{
static final WSServer instance = new WSServer();
public static WSServer getInstance(){
return SingletionWSServer.instance;
private EventLoopGroup mainGroup;
private EventLoopGroup subGroup;
private ServerBootstrap server;
private ChannelFuture future;
public WSServer(){
mainGroup = new NioEventLoopGroup();
subGroup = new NioEventLoopGroup();
server = new ServerBootstrap();
server.group(mainGroup,subGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new WSServerInitializer());
public void start(){
this.future = server.bind(8088);
System.err.println("netty websocket server 启动完毕...");
接着在前端的WebSocket的onopen事件中定时发送一条数据就好了,对该数据不做处理,让服务器知道有请求发送,客户端还在就好了。
//后端每60秒检测一次,这里只要小于60秒就行了
socket.onopen:function(){
setInterval("CHAT.keepalive()", 50000);
keepalive: function() {
// 构建对象
var dataContent = "test alive";
// 发送心跳
socket.send(dataContent);
为了适应恶劣的网络环境,比如网络超时、闪断,客户端进程僵死,Netty需要机制来保证双方的通信能正常工作或者自动恢复。对于服务端来说,当客户端由于某些原因导致无法与服务端通信的,服务端需要主动注销与客户端的连接,减少无效链接的资源消耗。对于客户端来说,当服务进程宕机后进行重启,客户端应该能够定时检测并重新连接服务端。
APP打开
请访问一下链接:
https://mp.weixin.qq.com/s?__biz=MzI4NjI2OTYwNg==&mid=2247484281&idx=1&sn=d6b308929da114da4bdafe93a590711f&chksm=ebdecab0dca943a67a9734d600c886c84c057a15f17ca4eeb06202c4c7e184...
APP打开
二、定时任务维护成本;
Netty提供了IdleStateHandler 来进行心跳检测。
通过使用ch.pipeline().addLast(new IdleStateHandler(0,0,5, TimeUnit.SECOND...
APP打开
Netty是一个NIO客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化并简化了TCP和UDP套接字服务器等网络编程。
“快速简便”并不意味着最终的应用程序会受到可维护性或性能问题的影响。Netty经过精心设计,具有丰富的协议,如FTP,SMTP,HTTP以及各种二进制和基于文本的传统协议。因此,Netty成功地找到了一种在不妥协的情况下实现易于开...
APP打开