經過學習前面的內容,你們基本可使用netty來開發程序了,本文再補充一下心跳檢測部分,屬因而完善功能的內容了。數據庫
大部分人聽到心跳鏈接這個名詞都是在數據庫鏈接池上,他的主要做用是發現長期不用的鏈接,就關閉掉,減輕服務器的鏈接壓力。在不少異常場合,例如客戶端強行殺掉等等,形成了程序不是正常退出的,服務器端的socket不少都是客戶端發消息而後響應的這種模式,客戶端不發送了,只有服務端再經過socket發送消息時才知道,原來已經鏈接斷了,並且還一直浪費socket資源(socket是算文件描述符數的,不少系統都有文件描述符的個數限制)。心跳檢測就是爲了防止這種浪費的手段,要求雙方定時必須收到消息,不然認爲應該鏈接斷開。這個場景在現實生活中也很場景,你們約定什麼時間見面,約定時間到了,人沒來,最多等5分鐘就走,只要5分鐘內收到信息,就能夠選擇繼續等仍是直接走,並不會無限期的等待下去。服務器
netty提供了心跳檢測類IdleStateHandler。他的三個參數,分別是讀超時時間,寫超時時間,讀寫超時時間。網絡
通常狀況下,服務端是看讀超時,就是看客戶端多久沒有發送消息了,這個須要根據業務來,大部分狀況都是這樣的。socket
ch.pipeline().addLast(new IdleStateHandler(10, 0, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(new ServerHeartBeat());
這裏檢測到有超時,就會發送事件,咱們還須要作一個事件處理,時間0表示不監控。ide
public class ServerHeartBeat extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) {//超時事件 IdleStateEvent idleEvent = (IdleStateEvent) evt; if (idleEvent.state() == IdleState.READER_IDLE) {//讀 ctx.channel().close(); } else if (idleEvent.state() == IdleState.WRITER_IDLE) {//寫 } else if (idleEvent.state() == IdleState.ALL_IDLE) {//所有 } } super.userEventTriggered(ctx, evt); } }
咱們如今的場景只對讀作處理,爲了方便,這裏列出了全部的事件。學習
咱們能夠啓動telnet來測試一下,看看10秒不發送數據,會不會形成鏈接斷開。測試
客戶端通常是寫超時,就是多久沒有寫數據了,此時就須要發送一個心跳包,告訴服務器端本身還在鏈接着。心跳包其實就是一個自定義的內容,通常不拿有意義的消息來發送,會選擇比較短的內容來保證不會形成網絡壓力。netty
ch.pipeline().addLast(new IdleStateHandler(0, 4, 0, TimeUnit.SECONDS)); ch.pipeline().addLast(new ClientHeartBeat());
客戶端監聽寫事件code
public class ClientHeartBeat extends ChannelInboundHandlerAdapter { @Override public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof IdleStateEvent) { IdleStateEvent idleEvent = (IdleStateEvent) evt; if (idleEvent.state() == IdleState.READER_IDLE) { } else if (idleEvent.state() == IdleState.WRITER_IDLE) { ctx.channel().writeAndFlush("hello"); } else if (idleEvent.state() == IdleState.ALL_IDLE) { } } super.userEventTriggered(ctx, evt); } }
當發現超時的時候,就去寫一條信息。事件
啓動這樣的客戶端就保證了不被服務端的檢測關閉了。
心跳檢測是經常使用的方式對鏈接作處理,使用netty提供的IdleStateHandler幫咱們省去了本身維護的狀況。本文舉出的場景是比較常見的一種,並非全部的都得這麼寫, 也有服務端監控寫事件,客戶端監控讀事件,或者所有都監控的場景,這些須要根據業務來分析製做。