Java長(zhǎng)連接指的是保持長(zhǎng)時(shí)間的連接,以便實(shí)現(xiàn)實(shí)時(shí)通信或推送新數(shù)據(jù)。在傳輸過(guò)程中,客戶(hù)端和服務(wù)器需要不斷有通訊才能保持連接,但長(zhǎng)時(shí)間的連接也會(huì)對(duì)服務(wù)器造成壓力。為了降低服務(wù)器的負(fù)擔(dān),需要使用心跳包機(jī)制,讓客戶(hù)端和服務(wù)器定期發(fā)送“心跳”,以保持連接。
public class KeepAliveHandler extends ChannelDuplexHandler { private ScheduledFuture<?> keepAlive; @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { if ("ping".equalsIgnoreCase(msg.toString())) { //收到ping,則回復(fù)pong ctx.writeAndFlush("pong"); } else if ("pong".equalsIgnoreCase(msg.toString())) { //收到pong,則重新開(kāi)始計(jì)時(shí) keepAlive = ctx.executor().scheduleAtFixedRate( new Runnable() { @Override public void run() { ctx.writeAndFlush("ping"); } }, 5, 5, TimeUnit.SECONDS); } else { super.channelRead(ctx, msg); } } @Override public void channelActive(ChannelHandlerContext ctx) { keepAlive = ctx.executor().scheduleAtFixedRate( new Runnable() { @Override public void run() { ctx.writeAndFlush("ping"); } }, 5, 5, TimeUnit.SECONDS); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) { keepAlive.cancel(false); super.channelInactive(ctx); } }
上述代碼實(shí)現(xiàn)了一個(gè)心跳包處理器,當(dāng)收到服務(wù)器的ping,客戶(hù)端會(huì)回復(fù)pong;當(dāng)收到pong后,客戶(hù)端將會(huì)定期發(fā)送ping,此處定時(shí)器為5秒。