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()
}
}