之前的兩篇關於如何使用OkHttp來實現WebSocket通信,然後有很多小夥伴私信問我如何實現斷線重連,今天我就把我項目中實現的重連機制代碼貼出來:
(我的實現思想就是基於斐波那契數列來進行嘗試重連)
1. 抽象的接口:
interface IRetryStrategy {
fun retry(url: String)
fun reset()
}
2. 重連策略實現類:
class FibonacciRetryStrategyImpl : IRetryStrategy {
private var lastTimeInterval: Long = 0
private var currentTimeInterval: Long = 1
private var subscriber: DisposableSubscriber<Long>? = null
override fun retry(url: String) {
var retryInterval = lastTimeInterval + currentTimeInterval
lastTimeInterval = currentTimeInterval
currentTimeInterval = retryInterval
if (retryInterval > MAX_INTERVAL) {
retryInterval = MAX_INTERVAL
}
logi { "retryInterval = $retryInterval" }
subscriber?.dispose()
subscriber = Flowable.intervalRange(0, retryInterval, 0, 1, TimeUnit.SECONDS)
.subscribeWith(object : DisposableSubscriber<Long>() {
override fun onComplete() {
WsManager.getInstance().connect(url)
}
override fun onNext(t: Long?) {}
override fun onError(t: Throwable?) {}
})
}
override fun reset() {
lastTimeInterval = 0
currentTimeInterval = 1
subscriber?.dispose()
subscriber = null
}
companion object {
private const val MAX_INTERVAL = 3600L //即一個小時
}
}
代碼很簡單,重連策略就是間隔1s,2s,3s,5s,8s... 類似一個斐波那契數列,如果超過一個小時,就按一個小時算。因爲我的項目是一個嵌入式設備,所以按照這種策略是ok的。
3. 調用:
3.1 在onFailure方法裏:
retryStrategy.retry(WS_DEVICE)
3.2 在onOpen方法裏:
retryStrategy.reset()
最後:大家可以根據自己項目的需求進而實現斷線重連機制,我這裏貼出來只是提供一種參考。