SignalR ——Android實(shí)踐

SignalR 的版本:aspnetcore-2.2, Java SignalR-1.0.0

一像寒、先說幾個(gè)點(diǎn)

1项秉、我使用SignalR的時(shí)候服務(wù)器使用的是自簽名的HTTPS證書,所以O(shè)kHttp是無法直接解析的僵蛛,會(huì)報(bào)錯(cuò)。需要修改SignalR里面OkHttp部分的源碼,讓其信任所有的HTTPS連接檐蚜。當(dāng)然,我這個(gè)項(xiàng)目是在內(nèi)部網(wǎng)絡(luò)里面使用的囤屹,所以才直接對(duì)信任了所有的HTTPS連接熬甚。

2、還有SignalR的版本問題肋坚,服務(wù)端的版本和客戶端的版本一定要匹配乡括。我剛開始做的時(shí)候服務(wù)端是不知道用的哪個(gè)版本的,也沒給我說清楚智厌。我是直接按照微軟官網(wǎng)的SignalR的文檔來寫的诲泌,但是與后臺(tái)對(duì)接的時(shí)候卻連不上,最后后臺(tái)是換成了我的那個(gè)客戶端對(duì)應(yīng)的SignalR的服務(wù)器版本才連接成功的铣鹏。

3敷扫、SignalR的引入
如果不需要對(duì)HTTPS進(jìn)行全部信任的話可以直接引入微軟官方的SignalR的Java版SDK

//gradle
implementation 'com.microsoft.signalr:signalr:1.0.0'

如果需要的話就可以下載我修改過的SignalR,主要就是對(duì)里面的OkHttp加個(gè)一個(gè)Https的全部信任。
https://github.com/lfork/androiddemo/signalr

二葵第、相關(guān)代碼(Kotlin)

建立連接

關(guān)鍵類com.microsoft.signalr.HubConnection和com.microsoft.signalr.HubConnectionBuilder

  val hubConnection = HubConnectionBuilder.create(serverUrl)
                .build()

  hubConnection.start().blockingAwait()

注意需要調(diào)用blockingAwait()來等待連接成功绘迁,我之前寫的時(shí)候沒有加,然后在調(diào)用 hubConnection.start()后直接就調(diào)用了向服務(wù)器發(fā)送消息的方法卒密,這樣子會(huì)發(fā)送失敗缀台。因?yàn)槟氵B接都沒建立好,所以要先等下哮奇。

關(guān)閉連接

 hubConnection.stop()

對(duì)被動(dòng)關(guān)閉進(jìn)行監(jiān)聽(比如網(wǎng)絡(luò)異常)

hubConnection.onClosed {
}

客戶端調(diào)用服務(wù)端方法

 /**
     * Invokes a hub method on the server using the specified method name.
     * Does not wait for a response from the receiver.
     *
     * @param method The name of the server method to invoke.
     * @param args   The arguments to be passed to the method.
     */
    public void send(String method, Object... args)

從SignalR源碼可以看到膛腐,我們只需要把服務(wù)端注冊好的方法名和參數(shù)傳遞進(jìn)行即可

eg

  hubConnection.send("SendMessageAsync", "" + "連接測試", "test")

服務(wù)端調(diào)用客戶端方法

客戶端需要在hubConnection對(duì)象執(zhí)行start()方法之前對(duì)服務(wù)端需要調(diào)用的方法進(jìn)行注冊。然后就可以接收服務(wù)端的消息了鼎俘。

①刪除用戶

//定義處理用戶刪除的action(方法體)
 val deleteAction = { id: String ->
    Log.d("SignalRSyncTask", "刪除用戶 $id")
    //doSomthing()
    Unit
 }

//對(duì)action進(jìn)行注冊
//第一個(gè)參數(shù)是對(duì)方法名的注冊哲身,第二個(gè)參數(shù)相當(dāng)于方法體,第三個(gè)參數(shù)就是客戶端注冊方法的參數(shù)了贸伐,
//我們可以看到deleteAction的lambda里面寫了一個(gè)id:String勘天。
hubConnection.on("DeleteUser", deleteAction, String::class.java)

②添加或者更新用戶

//定義處理相關(guān)的action(方法體)
val addOrUpdateAction = { userInfoModel: User ->
    Log.d("SignalRSyncTask", "添加或者更新用戶 ${userInfoModel.id}")
        userInfoChangedListenerList.forEach {
            it.userAddedOrUpdated(userInfoModel)
        }
    Unit
}

//對(duì)action進(jìn)行注冊
hubConnection?.on("AddOrUpdateUser", addOrUpdateAction, User::class.java)

完整代碼參考

代碼里面還維護(hù)了一個(gè)監(jiān)聽,開啟signalR的時(shí)候可以進(jìn)行監(jiān)聽的注冊棍丐,如果服務(wù)端有調(diào)用客戶端方法的話就會(huì)進(jìn)行提醒

import android.util.Log
import com.lfork.frtest.FRApplication
import com.lfork.frtest.data.userinfo.User
import com.lfork.frtest.syncservice.tasklistener.UserInfoChangedListener
import com.microsoft.signalr.HubConnection
import com.microsoft.signalr.HubConnectionBuilder
import java.lang.Exception

/**
 * Created by L.Fork
 *
 * @author lfork@vip.qq.com
 * @date 2019/01/28 18:01
 */
class SignalRSyncTask {
    private var hubConnection: HubConnection? = null

    private var userInfoChangedListenerList = ArrayList<UserInfoChangedListener>()

    fun start(serverUrl:String) {

        FRApplication.mThreadPool?.execute {
            hubConnection = HubConnectionBuilder.create(serverUrl)
                .build()

            hubConnection?.onClosed {close() }

            val connectionTestAction = { name: String, message: String ->
                Log.d("SignalRSyncTask", "SignalR 連接成功 $name - $message")
                Unit
            }

            val addOrUpdateAction = { userInfoModel: User ->
                Log.d("SignalRSyncTask", "添加或者更新用戶 ${userInfoModel.id}")
                userInfoChangedListenerList.forEach {
                    it.userAddedOrUpdated(userInfoModel)
                }
                Unit
            }

            val deleteAction = { id: String ->
                Log.d("SignalRSyncTask", "刪除用戶 $id")
                userInfoChangedListenerList.forEach {
                    it.userDeleted(id.toInt())
                }
                Unit
            }



            hubConnection?.on(
                "ReciveMessage",
                connectionTestAction,
                String::class.java,
                String::class.java
            )

            hubConnection?.on("AddOrUpdateUser", addOrUpdateAction, User::class.java)

            hubConnection?.on("DeleteUser", deleteAction, String::class.java)


            try {
                //This is test blocking call
                hubConnection?.start()?.blockingAwait()

                hubConnection?.send("SendMessageAsync", "" + "連接測試", "test")
            } catch (e:Exception){
                e.printStackTrace()
            }

        }

    }

    fun addUserInfoChangedListener(userInfoChangedListener: UserInfoChangedListener) {
        userInfoChangedListenerList.add(userInfoChangedListener)
    }

    fun close() {
        userInfoChangedListenerList.clear()
        hubConnection?.stop()
    }


}

三误辑、參考文檔

Microsoft官方參考文檔

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市歌逢,隨后出現(xiàn)的幾起案子巾钉,更是在濱河造成了極大的恐慌,老刑警劉巖秘案,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰苍,死亡現(xiàn)場離奇詭異,居然都是意外死亡阱高,警方通過查閱死者的電腦和手機(jī)赚导,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來赤惊,“玉大人凰荚,你說我怎么就攤上這事旋恼∠冢” “怎么了粥鞋?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長裕膀。 經(jīng)常有香客問我员串,道長,這世上最難降的妖魔是什么昼扛? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任寸齐,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘渺鹦。我一直安慰自己扰法,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布海铆。 她就那樣靜靜地躺著迹恐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卧斟。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天憎茂,我揣著相機(jī)與錄音珍语,去河邊找鬼。 笑死竖幔,一個(gè)胖子當(dāng)著我的面吹牛板乙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拳氢,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼募逞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了馋评?” 一聲冷哼從身側(cè)響起放接,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎留特,沒想到半個(gè)月后纠脾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蜕青,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年苟蹈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片右核。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡慧脱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出贺喝,到底是詐尸還是另有隱情菱鸥,我是刑警寧澤,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布搜变,位于F島的核電站采缚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挠他。R本人自食惡果不足惜扳抽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贸呢,春花似錦镰烧、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至固蛾,卻和暖如春结执,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背艾凯。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來泰國打工献幔, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趾诗。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓蜡感,卻偏偏與公主長得像,于是被迫代替她去往敵國和親恃泪。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郑兴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348