SignalR ——Android实践
SignalR 的版本:aspnetcore-2.2, Java SignalR-1.0.0
一、先說幾個點
1、我使用SignalR的時候服務器使用的是自簽名的HTTPS證書,所以OkHttp是無法直接解析的,會報錯。需要修改SignalR里面OkHttp部分的源碼,讓其信任所有的HTTPS連接。當然,我這個項目是在內部網絡里面使用的,所以才直接對信任了所有的HTTPS連接。
2、還有SignalR的版本問題,服務端的版本和客戶端的版本一定要匹配。我剛開始做的時候服務端是不知道用的哪個版本的,也沒給我說清楚。我是直接按照微軟官網的SignalR的文檔來寫的,但是與后臺對接的時候卻連不上,最后后臺是換成了我的那個客戶端對應的SignalR的服務器版本才連接成功的。
3、SignalR的引入
如果不需要對HTTPS進行全部信任的話可以直接引入微軟官方的SignalR的Java版SDK
如果需要的話就可以下載我修改過的SignalR,主要就是對里面的OkHttp加個一個Https的全部信任。
https://github.com/lfork/androiddemo/signalr
二、相關代碼(Kotlin)
建立連接
關鍵類com.microsoft.signalr.HubConnection和com.microsoft.signalr.HubConnectionBuilder
val hubConnection = HubConnectionBuilder.create(serverUrl).build()hubConnection.start().blockingAwait()注意需要調用blockingAwait()來等待連接成功,我之前寫的時候沒有加,然后在調用 hubConnection.start()后直接就調用了向服務器發送消息的方法,這樣子會發送失敗。因為你連接都沒建立好,所以要先等下。
關閉連接
hubConnection.stop()對被動關閉進行監聽(比如網絡異常)
hubConnection.onClosed { }客戶端調用服務端方法
/*** 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源碼可以看到,我們只需要把服務端注冊好的方法名和參數傳遞進行即可
eg
服務端調用客戶端方法
客戶端需要在hubConnection對象執行start()方法之前對服務端需要調用的方法進行注冊。然后就可以接收服務端的消息了。
①刪除用戶
//定義處理用戶刪除的action(方法體)val deleteAction = { id: String ->Log.d("SignalRSyncTask", "刪除用戶 $id")//doSomthing()Unit}//對action進行注冊 //第一個參數是對方法名的注冊,第二個參數相當于方法體,第三個參數就是客戶端注冊方法的參數了, //我們可以看到deleteAction的lambda里面寫了一個id:String。 hubConnection.on("DeleteUser", deleteAction, String::class.java)②添加或者更新用戶
//定義處理相關的action(方法體) val addOrUpdateAction = { userInfoModel: User ->Log.d("SignalRSyncTask", "添加或者更新用戶 ${userInfoModel.id}")userInfoChangedListenerList.forEach {it.userAddedOrUpdated(userInfoModel)}Unit }//對action進行注冊 hubConnection?.on("AddOrUpdateUser", addOrUpdateAction, User::class.java)完整代碼參考
代碼里面還維護了一個監聽,開啟signalR的時候可以進行監聽的注冊,如果服務端有調用客戶端方法的話就會進行提醒
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? = nullprivate 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 callhubConnection?.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官方參考文檔
?
作者:lfork
原文地址:?https://www.jianshu.com/p/43c79a7d0e3a
總結
以上是生活随笔為你收集整理的SignalR ——Android实践的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在web api中使用SignalR
- 下一篇: 2019全球开发者调查:仅2%的人996