1. 程式人生 > >Android通過WebSocket建立一個長連線(帶心跳檢測)從伺服器端接收訊息

Android通過WebSocket建立一個長連線(帶心跳檢測)從伺服器端接收訊息

   最近公司要做一款內部使用的工具類app,方便銷售部門打電話(其實就是在後臺有好多使用者資料,之前銷售部門同事撥打電話,需要自己從銷售後臺檢視使用者手機號等資訊,然後自己拿自己手機撥號,然後打出去。現在想實現銷售的同事,點選銷售後臺的按鈕,自己的手機直接撥號的功能)。為此,開始著手思考,怎麼實現銷售後臺點選按鈕,手機app端能收到點選按鈕的監聽。

  首先,後臺提供一個介面,在伺服器端不斷的呼叫介面以監聽後臺按鈕的點選事件以及收到後臺傳過來的資訊。這樣太繁瑣,而且不斷的調介面,比較耗效能,肯定不合適。然後想到建立一個長連線,在app端寫一個長連線(用Socket或者WebSocket),並加入心跳檢測,定期的去檢測長連線是否連線正常,如果連線中斷,執行重新連線。於是乎自己寫了個Socket的長連線,加入了心跳檢測。但是等和後臺聯調的時,後臺的同事提議用WebSocket長連線,這樣也許能方便些。於是自己又不情願的把Socket長連線換成WebSocket方式實現的長連線。還好我網路請求用的鴻洋大神的OkttpUtils,裡面提供了一個關於WebSocket連線的回撥。最終實現了這一功能。好了廢話不多說,上程式碼了。。。。

1.首先需要在AndroidManifest.xml中開啟一個服務:

<!-- 後臺服務-長連線 -->
<service android:name=".service.BackService" />

2.寫一個類BackService繼承Service:

public class BackService extends Service{
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

3.在BackService的onCreate()方法中開啟一個執行緒:

   @Override
    public void onCreate() {
        super.onCreate();
        new InitSocketThread().start();
    }

class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            try {
                initSocket();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 心跳檢測時間
     */
    private static final long HEART_BEAT_RATE = 15 * 1000;//每隔15秒進行一次對長連線的心跳檢測
    private static final String WEBSOCKET_HOST_AND_PORT = "ws://xxx:9501";//可替換為自己的主機名和埠號
    private WebSocket mWebSocket;
    // 初始化socket
    private void initSocket() throws UnknownHostException, IOException {
        OkHttpClient client = new OkHttpClient.Builder().readTimeout(0, TimeUnit.MILLISECONDS).build();
        Request request = new Request.Builder().url(WEBSOCKET_HOST_AND_PORT).build();
        client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {//開啟長連線成功的回撥
                super.onOpen(webSocket, response);
                mWebSocket = webSocket;
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {//接收訊息的回撥
                super.onMessage(webSocket, text);
                //收到伺服器端傳過來的訊息text
            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                super.onMessage(webSocket, bytes);
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t, @Nullable Response response) {//長連線連線失敗的回撥
                super.onFailure(webSocket, t, response);
            }
        });
        client.dispatcher().executorService().shutdown();
        mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//開啟心跳檢測
    }

4.開啟心跳檢測:

private long sendTime = 0L;
// 傳送心跳包
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                boolean isSuccess = mWebSocket.send("");//傳送一個空訊息給伺服器,通過傳送訊息的成功失敗來判斷長連線的連線狀態
                if (!isSuccess) {//長連線已斷開
                    mHandler.removeCallbacks(heartBeatRunnable);
                    mWebSocket.cancel();//取消掉以前的長連線
                    new InitSocketThread().start();//建立一個新的連線
                } else {//長連線處於連線狀態
                    
                }

                sendTime = System.currentTimeMillis();
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);//每隔一定的時間,對長連線進行一次心跳檢測
        }
    };

5.當BackService關閉時,關閉掉長連線:

@Override
    public void onDestroy() {
        super.onDestroy();
        if (mWebSocket != null) {
            mWebSocket.close(1000, null);
        }
    }
    好了!至此,建立一個與伺服器的帶心跳檢測的長連線就已實現完畢。至於我們的需求點選銷售後臺撥打電話按鈕,手機自動撥打電話的功能,也有了眉目。就是銷售後臺點選按鈕同時通過長連線傳一個手機號給前端app,在WebSocket接受訊息回撥的onMessage方法中,會接收到銷售後臺傳過來的手機號碼。app接收到手機號碼後,呼叫系統撥打電話的功能。就實現了這一需求。
   Ok,到此結束!有問題的朋友,可以在評論中留言哦,看到留言後,我會第一時間回覆!謝謝大家的支援,有不足之處,歡迎大家指正。如果你覺得不錯可以互相新增關注哦,後面有一些經驗我們大家互相分享,互相學習!

相關推薦

Android通過WebSocket建立一個連線心跳檢測伺服器接收訊息

   最近公司要做一款內部使用的工具類app,方便銷售部門打電話(其實就是在後臺有好多使用者資料,之前銷售部門同事撥打電話,需要自己從銷售後臺檢視使用者手機號等資訊,然後自己拿自己手機撥號,然後打出去。現在想實現銷售的同事,點選銷售後臺的按鈕,自己的手機直接撥號的功能)。為此

如何快速建立一個VUE專案介紹專案結構

建立vue專案流程 1.安裝node.js 首先檢視一下你的node.js是否安裝成功,如果安裝成功第一步可以略過。 驗證是否安裝成功 node -v #檢視nodejs版本號 比如:v8.4.0 如果未安裝,windows 在官網下載安裝包,直接安裝即可

建立一個maven專案非web專案

1、在啟動頁面選擇Create New Project後,會出現如下: 選擇Maven專案後,勾選 Create from archetype。對於非web專案,選擇maven-archetype-quickstart 能快速建立一個普通maven專案。

JAVA連線demo心跳檢測

package houlei.csdn.keepalive;   import java.io.Serializable;   import java.text.SimpleDateFormat;   import java.util.Date;  

pixhawk自學筆記之建立一個應用程式按官網

當把環境搭建好,整個工程下載後,開啟src-->examples--->px4_simple_app。 當然了,也可以自己新增想實現的功能和任務。當寫好這些應用程式,還要考慮要把它註冊為NuttShell命令。為了使該應用程式進入韌體的編譯,將其新增到模組

Netty實現服務客戶連線通訊及心跳檢測

通過netty實現服務端與客戶端的長連線通訊,及心跳檢測。       基本思路:netty服務端通過一個Map儲存所有連線上來的客戶端SocketChannel,客戶端的Id作為Map的key。每次伺服器端如果要向某個客戶端傳送訊息,只需根據ClientId取出對應的So

客服方式get請求中文伺服器接收解析是出現亂碼

中文亂碼處理 發生中文亂碼的三種情況及解決方案   表單form(傳送端分別採用get、post方式,接收端對應的解決辦法)  post:在接收的地方新增request.setCharacterEnc

Android通過socket.io實現連線

在專案開發中,時常有服務端向客戶端主動發起交流的需求,可以整合極光推送,但是如果網路不好的情況下,推送可能會遲遲收不到,這樣就導致了使用者體驗得不到保證。 若改用socket實現長連線的話,速度就快很

通過WebSocket建立連結實時獲取資料

     前段時間公司在做的一個專案,需要實時獲取到最新的行情資料,行情資料每秒更新,當時考慮過用輪詢方式獲取,但是稍微推敲,很是不妥。當用戶量多了,每個客戶端都要去輪詢伺服器,給伺服器造成的壓力很大大

基於Socket的TCP連線服務Java+客戶Android,Service配合AIDL實現

最近公司的專案要求加入訊息推送功能,由於專案使用者量不是很大,推送需求不是很嚴格,而且是基於內網的推送,所以我捨棄了使用三方的推送服務,自己使用Socket寫了推送功能,剪出一個小Demo來跟大家分享一下,有不足之處希望讀者能夠多多給出建議。 關於Socket的

經驗總結-完整介紹Android Studio中Git的使用之在GitHub上建立一個遠端倉庫

說完本地Git倉庫,那麼如何將專案上傳至遠端的GitHub倉庫呢?首先我們需要有一個託管平臺,然後需要建立一個倉庫。現在我們開始註冊一個GitHub賬號,然後去後new 一個倉庫吧: 一、首先我們需

『中級篇』手動建立一個base Image14

執行 安裝 build imageview orien ogr 微信 微信公眾號 gcc 這篇文章主要介紹了Docker Base Image創建具體實現的相關資料,這裏提供了詳細的具體步驟,需要的朋友可以參考下github:https://github.com/limin

Android之列印日誌兩種方法

//第一種方式 //列印長的日誌 public static void LongLoge(String str){ int max_str_length=2001-NOTGREENDAO.length(); //大於4000時

安裝Git和建立一個倉庫repository

這裡講的是windows 安裝Git: 要使用Git,第一步當然是安裝Git了。根據你當前使用的平臺來閱讀下面的文字: 在Windows上使用Git,可以從Git官網直接下載安裝程式,然後按預設選項安裝即可。 安裝完成後,在開始選單裡找到“Git”->“Git Bash”,蹦出一個類似

使用IntelliJ IDEA通過Maven建立Spring的HelloWord超詳細圖文教程

在JavaWeb中,隨著Intellij IDEA的廣泛使用,所用的Maven外掛在以後的JavaEE中開發也將是個趨勢,通過Maven倉庫,我們可以不用下載所關聯的Jar包就可以進行引用,還是很方便整個工程管理的。 因為自己也是第一次接觸Spring專案,而且前前後後鼓搗了十多次,

Android基礎篇——建立一個Android工程

Android系列停了兩個月,電腦還是沒弄好,記憶體不能外拓。現在把windows換成了ubuntu,再裝AS,發現雖然還是卡,但不至於卡到宕機。所以又出來折騰啦。 今天正式開始Android的開發系列,初始階段當然從建立一個Android工程開始: 下面是步驟: 1.開啟As,滑

Android如何獲取視訊預覽圖或首幀和獲取視訊時

Android獲取視訊預覽圖(或首幀)和獲取時長需要用到MediaMetadataRetriever類,獲取預覽圖使用getFrameAtTime()方法,獲取時長使用extractMetadata(MediaMetadataRetriever.METADATA_KEY_DU

Android 與AP模式下的硬體連線嵌入式基礎需求

Android客戶端開發可以大致分為兩種,一是純客戶端APP開發,像某寶,某東,二是與硬體進行互動的APP,比如家庭WiFi、掃碼乘地鐵等。我之前是做純客戶端開發,並未與硬體進行互動開發過,也是懷著諸多猜測進入目前的公司,也是僅僅用了十天左右的時間由0到1的快速開發了一款他們需要的產品…之前

Android(或者Java)通過HttpUrlConnection向SpringMVC請求資料資料繫結

問題描述     當我們使用SpringMVC作為服務端的框架時,有時不僅僅要應對web前端(jsp、javascript、Jquery等)的訪問請求,有時還可能需要響應Android和JavaSE(桌面應用)這些客戶端的請求,因此,除了web使用form表單