1、客戶端代碼存在的必要性以及我認爲須要解決的問題java
就NIO通信自己而言徹底不必分開,其實客戶端代碼和服務端代碼能夠放到一塊兒。可是在業務上是分開的。我在作nio的時候思考了許多我本身認爲應該解決的問題;主要的以下:線程
一、鏈路維護(心跳);code
按期的向服務端發送維持鏈路報文,得到服務端的響應,以證實其仍然在存活狀態;同時服務端會記錄客戶端每次維持鏈路的時間,用於服務端對通道的超時 判斷;對象
二、斷線重連:get
一種狀況是正常斷線,目前我利用對channel的read返回來進行判斷;
it
另外一種是非正常短線,我利用維持鏈路的心跳回應來進行判斷,也就是說,當連續發送固定次數的維持鏈路指令,沒有收到服務端的迴應的時候,主動斷線,啓動重連;io
2、具體實現:class
一、鏈路維護代碼:channel
定時發送維持鏈路指令;
nio
判斷維持鏈路指令緩衝區(此緩衝區在每次發送維持鏈路指令的時候會將指令記錄到緩衝區,每次收到鏈路維護迴應報文的時候,會將其所對應的指令清除,若是連續屢次收不到迴應,那麼緩衝區的大小就會達到設置的閾值)的大小,若是達到預設值,就設置客戶端鏈接狀態爲false;重連線程會依據這個標記作是否重連的判斷。
public class KeepChannelThread extends Thread { private static Logger logger = LogManager.getLogger(KeepChannelThread.class.getName()); private int reconnectTag = 0; public void run(){ while(true){ //構建鏈路維護指令對象 ClientKeepOrder keepOrder = (ClientKeepOrder)Client.getOrderInstance(ClientKeepOrder.HEADER); keepOrder.initClientKeepOrder(); if (StringUtils.isBlank(keepOrder.getToken())){ logger.info("未收到服務端分配的身份標識,暫不發送鏈路維護報文!"); reconnectTag++; if (reconnectTag>Client.getKeepTimeoutCount()){ Client.clearToken4Disconnect(); } }else { reconnectTag = 0; try { //觸發重連機制 if (Client.KEEP_ORDER_MAP.size()>=Client.getKeepTimeoutCount()){ Client.clearToken4Disconnect(); logger.info("維持鏈路發現服務端未響應數量達到閾值,進行重連操做!"); continue; } //發送鏈路維持報文 Client.write2Channel(keepOrder); //保存鏈路維持報文到緩衝區,等待服務端迴應清除。 ClientKeepOrder keepOrderValue = new ClientKeepOrder(); keepOrderValue = keepOrder; Client.KEEP_ORDER_MAP.put(keepOrder.getRid(), keepOrderValue); } catch (IOException e) { e.printStackTrace(); continue; } } try { Thread.sleep(Client.getKeepAliveCycle()*1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }