1. 程式人生 > >即時通訊判斷網路狀態和斷線重連機制

即時通訊判斷網路狀態和斷線重連機制


本文借鑑csdn大神way的xmpp客戶端學習改造而來,不足之處希望大家多多指教!

 1. 由於近半年來一直寫針對於tigase伺服器的即時通訊軟體的開發,框架的重構,對即時通訊的理解也較之前更進一步,在客戶端的IM開發中,最重要的除去通訊的建立,就是保持網路環境不斷更換時,客戶端與伺服器端的長連線。

-具體實現的思路:

由於客戶端網路狀況不穩定,客戶端通過加入判斷網路狀態的工具類,來判斷網路是否重新連線,一旦網路狀態從無到有,便開啟斷線重連機制,重新登陸IM伺服器,登陸成功後,阻塞當前執行緒

2 判斷網路狀態的工具類

public class NetWorkUtils {

    /**
     * 沒有網路
     */
    public static final String NETWORKTYPE_INVALID = "NO";

    /**
     * 2G網路
     */
    public static final String NETWORKTYPE_2G = "2G";
    /**
     * 3G
     */
    public static final String NETWORKTYPE_3G = "3G";
    /**
     * 4G
     */
    public static final String NETWORKTYPE_4G = "4G";
    /**
     * wifi網路
     */
    public static final String NETWORKTYPE_WIFI = "WIFI";

    /**
     * wifi網路
     */
    public static final String NETWORKTYPE_UNKNOWN = "UNKNOWN";


    /**
     * 獲取當前網路型別
     *
     * @param context
     * @return 2G/3G/4G/WIFI/no/unknown
     */
    public static String getNetType(Context context) {
        ConnectivityManager cm = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        final NetworkInfo info = cm.getActiveNetworkInfo();
        if (info == null || !info.isAvailable()) {
            return NETWORKTYPE_INVALID;
        }
        if (info.getType() == ConnectivityManager.TYPE_WIFI) {
            return NETWORKTYPE_WIFI;
        }
        if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
            int sub = info.getSubtype();

            L.d("asker","網路型別"+sub);
            switch (sub) {

                case TelephonyManager.NETWORK_TYPE_GPRS:
                case TelephonyManager.NETWORK_TYPE_EDGE:
                case TelephonyManager.NETWORK_TYPE_CDMA://電信的2G
                case TelephonyManager.NETWORK_TYPE_1xRTT:
                case TelephonyManager.NETWORK_TYPE_IDEN:
                    //以上的都是2G網路
                    return NETWORKTYPE_2G;

                case TelephonyManager.NETWORK_TYPE_UMTS:
                case TelephonyManager.NETWORK_TYPE_EVDO_A:
                case TelephonyManager.NETWORK_TYPE_HSDPA:
                case TelephonyManager.NETWORK_TYPE_HSUPA:
                case TelephonyManager.NETWORK_TYPE_HSPA:
                case TelephonyManager.NETWORK_TYPE_EVDO_B:
                case TelephonyManager.NETWORK_TYPE_EHRPD:
                case TelephonyManager.NETWORK_TYPE_HSPAP:
                    //以上的都是3G網路
                    return NETWORKTYPE_3G;

                case TelephonyManager.NETWORK_TYPE_LTE:
                case 18:

                    return NETWORKTYPE_4G;

                case TelephonyManager.NETWORK_TYPE_UNKNOWN:

                    return NETWORKTYPE_INVALID;

                default:
                    return NETWORKTYPE_UNKNOWN;
            }
        }
        return NETWORKTYPE_UNKNOWN;

    }


    /*
    * 獲取IP地址
    *
    * */
    public static String getIPAddress(Context context) {

        if (NETWORKTYPE_WIFI.equals(getNetType(context))) {
            WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            // 獲取32位整型IP地址
            int ipAddress = wifiInfo.getIpAddress();

            //返回整型地址轉換成“*.*.*.*”地址
            return String.format("%d.%d.%d.%d",
                    (ipAddress & 0xff), (ipAddress >> 8 & 0xff),
                    (ipAddress >> 16 & 0xff), (ipAddress >> 24 & 0xff));
        } else {
            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface
                        .getNetworkInterfaces(); en.hasMoreElements(); ) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf
                            .getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()
                                && inetAddress instanceof Inet4Address) {
                            // if (!inetAddress.isLoopbackAddress() && inetAddress
                            // instanceof Inet6Address) {
                            return inetAddress.getHostAddress().toString();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";

        }
    }
}

3 斷線重連機制
/**
 * 斷線重連機制
 * Created by fflin on 2016/5/8.
 */
public class ReconnectionThread extends Thread {
    private LoginService loginService;
    private int reconnectCount;
    public ReconnectionThread(LoginService service) {
        this.loginService = service;
        this.reconnectCount = 0;
    }

    @Override
    public void run() {
        try {
            while (!isInterrupted()) {
                L.e("asker", "@@ 正在斷線重連 " + waitingTime()
                        + " seconds" + "; UrlConstant.jaxmpp.isConnected() :" + UrlConstant.jaxmpp.isConnected()
                        + "; isInterrupted() :" + isInterrupted());
                Thread.sleep((long) waitingTime() * 1000l);
                if (!UrlConstant.jaxmpp.isConnected()){
                    loginService.Login(); //重新登陸聊天伺服器
                    reconnectCount++;
                }else{
                    currentThread().interrupt(); //登陸成功阻塞當前執行緒
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private int waitingTime() {
        if (reconnectCount > 20) {
            return 600;
        }
        if (reconnectCount > 13) {
            return 300;
        }
        return reconnectCount <= 7 ? 5 : 60;
    }

}


相關推薦

即時通訊判斷網路狀態機制

本文借鑑csdn大神way的xmpp客戶端學習改造而來,不足之處希望大家多多指教!  1. 由於近半年來一直寫針對於tigase伺服器的即時通訊軟體的開發,框架的重構,對即時通訊的理解也較之前更進一步,在客戶端的IM開發中,最重要的除去通訊的建立,就是保持網路環境不斷更換時

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

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

手機客戶端弱網路下的處理

1、弱網路下的斷線重連   玩家在遊戲過程中,所處的網路環境是複雜多變的,可能是wifi的網路不穩定,或處在3G甚至2G的環境下等。在這些情況下,網路遊戲會由於網路或包量等原因而出現延遲,拉拽,甚至掉線等問題。對於這些問題,一方面要對程式的包量和通訊進行優化,從根本上減緩

使用netty進行客戶端網路程式設計及功能實現

       不管做哪個方向開發,都會有那麼一兩個牛B閃閃的庫,可以極大的方便開發,比如java網路程式設計中的netty庫。無論客戶端還是服務端網路程式設計,netty基本都是首選網路庫,健壯、高效、穩定,並且已經得到很多商業專案驗證。        當用netty進行客

Netty — 心跳檢測

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

ActiveMQ的機制

primary active 節點 語法 無限 機制 新的 bubuko 獲取 斷線重連機制是ActiveMQ的高可用性具體體現之一。ActiveMQ提供failover機制去實現斷線重連的高可用性,可以使得連接斷開之後,不斷的重試連接到一個或多個brokerURL。 默認

【android學習】機制

【解決問題】 android端連線網路之後,當網路斷開連線時,為了提高使用者體驗,android自動檢測網路,當有網路時,使用者無需進行多餘操作,android端自動重新連線網路。 【解決方案】 1、設定網路斷開連線標誌:NET_BAD 1)每次傳送資料,若傳送資料不成功,

Mina 機制

Mina 斷線重連     定義:這裡討論的Mina 斷線重連是指使用mina作為客戶端軟體,連線其他提供Socket通訊服務的伺服器端。Socket伺服器可以是Mina提供的伺服器,也可以是C++提供的伺服器。      一、斷線重連的方式;     1.

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

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

C# 判斷Socket

定時器裡面的事件 private void isConnendTimer_Tick(object sender, EventArgs e) { // 首先,Socket類的Connected屬性只表示最後一次I/

nodejs中mysql

調試 狀態 pan var 參考 ble prot nec clas 之前寫了個小程序Node News,用到了MySQL數據庫,在本地測試均沒神馬問題。放上服務器運行一段時間後,偶然發現打開頁面的時候頁面一直處於等待狀態,直到Nginx返回超時錯誤。於是上服務器檢查了遍,

android 實現mqtt訊息推送,以及不停的問題解決

前段時間專案用到mqtt的訊息推送,整理一下程式碼,程式碼的原型是網上找的,具體哪個地址已經忘記了。 程式碼的實現是新建了一個MyMqttService,全部功能都在裡面實現,包括連伺服器,斷線重連,訂閱訊息,處理訊息,釋出訊息等基本操作。 首先新增依賴: dependencies { &

django的資料庫

django每次查詢都會被把連線關閉,想保持長連線方法如下: from django.core import signals from django.db import close_connection # 取消訊號關聯,實現資料庫長連線 signals.request

【UE4】 第12講 FSocket

(版權宣告,禁止轉載) 【第03講】 實現了FSocket的連網基礎功能,這一講實現一下 斷線重連 <如果資深前輩發現有理解錯誤,還請不吝指正> <1> 建立Socket,設定阻塞模式(預設創建出來的就是阻塞模式,不用設定)  

teamtalk socket問題的查詢

之前從teamtalk的核心庫裡面剝離出一個跨平臺網路庫,一開始用的好好的,可是在某些地方使用的時候總是出怪問題,有時候斷線重連就一直連不上,導致應用失聯,在實際使用場景中一直出問題,好不尷尬。 經過連三天的苦思冥想,除錯程式碼看輸出終於有些眉目了。 我是從以下幾個方面著手解決的,特此記錄一

關於資料庫的一點點思考

最近在寫資料庫連結池,一個不可逃避的問題就是資料庫斷線重連。 查了很多資料,因為公司有很多專案用了 TP5 於是也去看了它的原始碼。 tp5的實現其實很簡單,配置了一些資料庫連線相關的錯誤資訊關鍵詞(句),然後在執行語句時 catch 異常資訊進行比對: // 伺服器斷線標識字元 p

Yii2實現mysql[轉載]

最近遇到“Yii2實現mysql斷線重連”問題,找了好久資料,最後找到這篇文件是說明了該情況的,感謝這位作者的分享,記錄下來,必備以後查閱。 原文連結:https://www.yiichina.com/topic/7296 Yii2實現資料庫斷線重連 一、前話 在工作中,有時候一

netty4.0 心跳檢測與操作

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

mqtt協議 springboot2.0.4 mqttv3 釋出訂閱程式碼呼叫,mqtt

mqttv3 釋出訂閱程式碼呼叫 我用的是springboot2.0.4 直接上程式碼: pom.xml <dependency> <groupId>org.eclipse.paho</groupId>

iOS MQTT使用案例 ()

iOS MQTT使用案例 (斷線重連) 參考了 iOS MQTT—-MQTTClient實戰-看這篇的就夠了 大神寫的這篇 git: MQTT-Client-Framework 介紹啥的看百度,上面大神寫的就行了,直接上乾貨。 安裝: pod 'MQTTClient'