1. 程式人生 > >socket心跳檢測和重連小demo

socket心跳檢測和重連小demo

        有時候我們的程式要求socket一直保持連線,並且希望在socket斷開以後能夠重新連線,這個時候就需要用到心跳機制,所謂心跳機制,最簡單的做法就是客戶端每隔一段時間向服務端傳送資料包,為了節約資源我們很多時候傳送空資料就好,如果資料不能傳送成功說明socket已經斷開,這個時候就需要根據具體需求釋放資源和重新連線了。

        下面給出一個簡單的小demo 

 /**
     * 連線服務端
     */
    private void connectToServer() {
        Thread connectThread = new Thread(new Runnable() {
            public void run() {
                try {
                    mSocket = new Socket();
                    mSocket.connect(
                            new InetSocketAddress(SOCKET_HOST, SOCKET_PORT));

                    Log.e(TAG, "連線成功  " + SOCKET_HOST);
                    mDataOutputStream = new DataOutputStream(
                            mSocket.getOutputStream());
                    
                    // 開啟執行緒負責讀取服務端資料
                    mReadThread = new SocketReadThread();
                    mReadThread.start();
                    
                    // 心跳檢測,檢測socket是否連線
                    mHandler.postDelayed(mHeartBeatRunnable, HEART_BEAT_RATE);
                } catch (UnknownHostException e) {
                    Log.e(TAG, "連線失敗  ");
                    e.printStackTrace();
                } catch (IOException e) {
                    Log.e(TAG, "連線失敗  ");
                    e.printStackTrace();
                }
            }
        });
        connectThread.start();
    }

         上述方法負責建立新的socket例項和開啟心跳檢測,其中比較重要的程式碼是
          mHandler.postDelayed(mHeartBeatRunnable, HEART_BEAT_RATE);
          這裡的HEART_BEAT_RATE是一個int常量,表示心跳間隔,mHeartBeatRunnableze則負責心跳檢測

// 心跳機制
    private SocketReadThread mReadThread;
    private static final long HEART_BEAT_RATE = 4 * 1000;
    private long sendTime = 0L;
    private Runnable mHeartBeatRunnable = new Runnable() {

        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {//每隔4秒檢測一次
                boolean isSuccess = sendHeartBeatMsg("");
                if (!isSuccess) {
                    Log.i(TAG, "連線已斷開,正在重連……");
                    mHandler.removeCallbacks(mHeartBeatRunnable);// 移除執行緒,重連時保證該執行緒已停止上次呼叫時的工作
                    mReadThread.release();//釋放SocketReadThread執行緒資源
                    releaseLastSocket();
                    connectToServer();// 再次呼叫connectToServer方法,連線服務端
                }
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };
    /**
     * 傳送心跳包
     * 
     * @param msg
     * @return
     */
    public boolean sendHeartBeatMsg(String msg) {
        if (null == mSocket) {
            return false;
        }
        try {
            if (!mSocket.isClosed() && !mSocket.isOutputShutdown()) {
                String message = msg + "\r\n";
                mDataOutputStream.write(message.getBytes());
                mDataOutputStream.flush();
                sendTime = System.currentTimeMillis();
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

        上述方法是心跳檢測的主要方法,呼叫sendHeartBeatMsg()傳送資料到服務端,該方法稍後給出。如果檢測到連線斷開,則釋放各種資源,重新連線。如果連線沒有斷開則繼續檢測,非常簡單的邏輯

/**
  * 斷開連線
  *
  */
    private void releaseLastSocket() {
        try {
            if (null != mSocket) {
                if (!mSocket.isClosed()) {
                    mSocket.close();
                }
            }
            mSocket = null;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

         最後給出SocketReadThread執行緒,這個執行緒負責讀取服務端傳送過來的資料,和心跳機制無關,但在心跳機制中重連處理時,一定要釋放它的資源。

public class SocketReadThread extends Thread {

        private static final String TAG = "SocketThread";
        private volatile boolean mStopThread = false;
        public void release() {
            mStopThread = true;
            releaseLastSocket();
        }
        @Override
        public void run() {
            DataInputStream mInputStream = null;
            try {
                mInputStream = new DataInputStream(mSocket.getInputStream());
                Logger.d(TAG, "SocketThread running!");
                while (!mStopThread) { 
                    String resultStr = mInputStream.readUTF();
                    handleStringMsg(resultStr);
                }
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    mSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (mInputStream != null) {
                    try {
                        mInputStream.close();
                        mInputStream = null;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }


相關推薦

socket心跳檢測demo

        有時候我們的程式要求socket一直保持連線,並且希望在socket斷開以後能夠重新連線,這個時候就需要用到心跳機制,所謂心跳機制,最簡單的做法就是客戶端每隔一段時間向服務端傳送資料包,為了節約資源我們

WebSocket的心跳檢測Spring的整合

最近搞好論文,對其中的WebSocket中相對比較實用的技術做一個總結,這個東西之前是用來作前後臺的監控資料的實時通訊,主要記錄一下心跳包和重連的過程,websocket中的心跳這裡是通過客戶端定義一個定時器實現,主要程式碼如下: //心跳檢測,每20s心跳一次 v

netty自定義訊息實現心跳檢測

其實客戶端心跳傳送用到的是IdleStateHandler,詳細看程式碼你就會明白為什麼。 //處理空閒狀態事件的處理器 pipeline.addLast(new IdleStateHandler(6,7,8, TimeUnit.SECONDS)); 在IdleSt

Netty — 心跳檢測斷線

心跳檢測 limit art segment 檢測 oot 通過 context serve 一.前言 由於在通信層的網絡連接的不可靠性,比如:網絡閃斷,網絡抖動等,經常會出現連接斷開。這樣對於使用長連接的應用而言,當突然高流量沖擊勢必會造成進行網絡連接,從而產生網絡堵塞,

Netty 之 Netty生產級的心跳機制

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

一起學Netty(十四)之 Netty生產級的心跳機制

sigh,寫這篇部落格的時候老臉還是紅了一下,心裡還是有些唏噓的,應該算是剽竊吧,每個人的程式碼功力的確是有差距的,好在文章的標題是“一起學”,而不是開濤大神的“跟我學”系列的文章,我們還是多花點時間學習吧,感嘆無用~ 最近工作比較忙,但閒暇之餘還是看了阿里的馮家春(fe

理解WebSocket心跳及中斷機制

在使用websocket的過程中,有時候會遇到網路斷開的情況,但是在網路斷開的時候伺服器端並沒有觸發onclose的事件。這樣會有:伺服器會繼續向客戶端傳送多餘的連結,並且這些資料還會丟失。所以就需要一種機制來檢測客戶端和服務端是否處於正常的連結狀態。因此就有了websocket的心跳了。還

Linux檔案壓縮,管道定向

1, 練習並熟練掌握Linux下常見壓縮格式 tar.bz2和tar.gz的壓縮與解壓縮; 並各給出壓縮與解壓縮例項;[[email protected] dir]$ tar -zcvf ./

Socket連線程式碼示例、WebService demo示例

最近面試遇到的問題 1:開閉原則 開放對原來程式碼的擴充套件,封閉對原來程式碼的修改 2:http協議 A : URL是http(超文字傳輸協議)是基於請求與響應模式的、無狀態的、應用層協議。長基於TCP的連線方式 B : HTTP請求,ht

三級聯動,struts2jdbc的DEMO

這幾天剛看完struts2,所以用struts2和JDBC做了一個增刪改查的小練習,裡邊也加了國家、省、市的三級聯動,也算順便複習,下邊貼程式碼。 先是Demo的檢視 先是配置檔案,struts.xml <?xml version="1.0" encoding="

Android開發中實現使用者註冊登陸的demo分享

本文例項講述了Android實現登入功能的方法。分享給大家供大家參考,具體如下: 登陸效果: 應用程式判斷當前使用者還未登陸,彈出登陸對話方塊,使用者輸入賬號和密碼資訊後,傳到伺服器驗證,驗證成功後,現實Toast 成功資訊,並轉到其他介面。 註冊效果:使

Spring,SpringMVChibernate整合demo

DeptController @Controller public class DeptController { //植入service @Resource private IDeptService deptService; @Reques

WebSocket在服務端客戶端通訊demo,支援心跳檢測+斷線

一、為什麼需要 WebSocket? 初次接觸 WebSocket 的人,都會問同樣的問題:我們已經有了 HTTP 協議,為什麼還需要另一個協議?它能帶來什麼好處? 答案很簡單,因為 HTTP 協議有一個缺陷:通訊只能由客戶端發起。 舉例來說,我們想了解今天的天氣,只能是客戶端向伺服器發出

長連線 、短連線、心跳機制與斷線(轉載) Socket的長連線短連線

概述 可承遇到,不知什麼原因,一個夜晚,機房中,大片的遠端呼叫連線斷開。 第二天早上,使用者訪問高峰,大部分伺服器都在獲取連線,造成大片網路阻塞。 服務崩潰,慘不忍睹的景象。 本文將從長連線和短連線的概念切入,再到長連線與短連線的區別,以及應用場景,引出心跳機制和斷線重連,給出程式碼實現。 從原

C++ TCP socket程式設計中的陷阱(服務端accept 不阻塞 客戶端connect 失敗)

在編寫一個使用C++ socket實現的TCP服務端與客戶端小軟體時接連碰上2個小陷阱, 終歸是實踐不足,基本功不紮實。 第1個問題: 服務端的accept函式沒有阻塞     程式執行到accept這裡時直接就跳了過去,根本沒停下來。     懷疑過socket

初探實現websocket心跳

需要 方法 0ms 實例化 並且 rtb code 控制 判斷 初探和實現websocket心跳重連 心跳重連緣由 在使用websocket過程中,可能會出現網絡斷開的情況,比如信號不好,或者網絡臨時性關閉,這時候websocket的連接已經斷開, 而瀏覽器不會執行webs

websocket 心跳 (通訊檢測

        最近做專案,用到websocket來做訊息的實時推送。在做這個專案之前,websocket的相關內容沒有接觸過,只限於知道有這個東西。對於這個websocket,一切都是從零開始。所以做這個專案前有去搜索了一些關於websocket的技術知識。      

netty4.0 心跳檢測與斷線操作

因為最近專案最近要用netty,服務端放在雲端,客戶端發在內網。那如何實現netty長連線和斷線重連呢(網路故障或者其他原因,客戶端要無限取重連服務端)。接下來我們看一下如何實現這個兩個功能呢。 服務端程式碼如下: package com.example.nettydem

Android Socket連線(模擬心跳包,斷線,傳送資料等)

這兩天做了一個專案是app通過socket連線自動炒菜機,給炒菜機發指令,炒菜機接收到指令會執行相應的操作。(程式雖然做的差不多了,然而我連炒菜機長什麼樣都沒見過) 其實作為一個會做飯的程式猿,我堅信還是自己動手做的飯菜比較好吃,畢竟做飯還是很有趣的。 閒話不

httpsocket之長接區別

系統 targe 多個參數 到來 備註 結構 span tin 設計 TCP/IP TCP/IP是個協議組,可分為三個層次:網絡層、傳輸層和應用層。 在網絡層有IP協議、ICMP協議、ARP協議、RARP協議和BOOTP協議。 在傳輸層中有TCP協議與UDP協議。 在應用層