mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-04-19 16:19:33 +01:00
Detect and recycle WebSockets stuck in connecting state.
This commit is contained in:
@@ -7,9 +7,16 @@ package org.thoughtcrime.securesms.net
|
||||
|
||||
import io.reactivex.rxjava3.kotlin.subscribeBy
|
||||
import io.reactivex.rxjava3.schedulers.Schedulers
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.net.SignalWebSocketHealthMonitor.Companion.KEEP_ALIVE_SEND_CADENCE
|
||||
import org.thoughtcrime.securesms.net.SignalWebSocketHealthMonitor.Companion.KEEP_ALIVE_TIMEOUT
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.whispersystems.signalservice.api.util.SleepTimer
|
||||
import org.whispersystems.signalservice.api.websocket.HealthMonitor
|
||||
@@ -49,6 +56,10 @@ class SignalWebSocketHealthMonitor(
|
||||
private var needsKeepAlive = false
|
||||
private var lastKeepAliveReceived: Duration = 0.seconds
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
private var connectingTimeoutJob: Job? = null
|
||||
private var failedInConnecting: Boolean = false
|
||||
|
||||
@Suppress("CheckResult")
|
||||
fun monitor(webSocket: SignalWebSocket) {
|
||||
executor.execute {
|
||||
@@ -69,11 +80,22 @@ class SignalWebSocketHealthMonitor(
|
||||
|
||||
private fun onStateChanged(connectionState: WebSocketConnectionState) {
|
||||
executor.execute {
|
||||
Log.v(TAG, "${webSocket?.connectionName} onStateChange($connectionState)")
|
||||
|
||||
when (connectionState) {
|
||||
WebSocketConnectionState.CONNECTING -> {
|
||||
connectingTimeoutJob?.cancel()
|
||||
connectingTimeoutJob = scope.launch {
|
||||
delay(if (failedInConnecting) 60.seconds else 30.seconds)
|
||||
Log.w(TAG, "${webSocket?.connectionName} Did not leave CONNECTING state, starting over")
|
||||
onConnectingTimeout()
|
||||
}
|
||||
}
|
||||
WebSocketConnectionState.CONNECTED -> {
|
||||
if (webSocket is SignalWebSocket.AuthenticatedWebSocket) {
|
||||
TextSecurePreferences.setUnauthorizedReceived(AppDependencies.application, false)
|
||||
}
|
||||
failedInConnecting = false
|
||||
}
|
||||
WebSocketConnectionState.AUTHENTICATION_FAILED -> {
|
||||
if (webSocket is SignalWebSocket.AuthenticatedWebSocket) {
|
||||
@@ -91,6 +113,13 @@ class SignalWebSocketHealthMonitor(
|
||||
|
||||
needsKeepAlive = connectionState == WebSocketConnectionState.CONNECTED
|
||||
|
||||
if (connectionState != WebSocketConnectionState.CONNECTING) {
|
||||
connectingTimeoutJob?.let {
|
||||
it.cancel()
|
||||
connectingTimeoutJob = null
|
||||
}
|
||||
}
|
||||
|
||||
updateKeepAliveSenderStatus()
|
||||
}
|
||||
}
|
||||
@@ -112,6 +141,13 @@ class SignalWebSocketHealthMonitor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun onConnectingTimeout() {
|
||||
executor.execute {
|
||||
webSocket?.forceNewWebSocket()
|
||||
failedInConnecting = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateKeepAliveSenderStatus() {
|
||||
if (keepAliveSender == null && sendKeepAlives()) {
|
||||
keepAliveSender = KeepAliveSender().also { it.start() }
|
||||
|
||||
Reference in New Issue
Block a user