fix: don't reconnect when command was superseded
We only want to do the reconnect if the previous command was the schedule reconnect, if the websocket connection got started another way or was closed, we don't want to do the reconnect.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
package com.github.gotify.service
|
package com.github.gotify.service
|
||||||
|
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
|
import android.app.AlarmManager.OnAlarmListener
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
@@ -29,9 +30,10 @@ internal class WebSocketConnection(
|
|||||||
private val ID = AtomicLong(0)
|
private val ID = AtomicLong(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var alarmManagerCallback: OnAlarmListener? = null
|
||||||
|
private var handlerCallback: Runnable? = null
|
||||||
private val client: OkHttpClient
|
private val client: OkHttpClient
|
||||||
private val reconnectHandler = Handler(Looper.getMainLooper())
|
private val reconnectHandler = Handler(Looper.getMainLooper())
|
||||||
private val reconnectCallback = Runnable { start() }
|
|
||||||
private var errorCount = 0
|
private var errorCount = 0
|
||||||
|
|
||||||
private var webSocket: WebSocket? = null
|
private var webSocket: WebSocket? = null
|
||||||
@@ -106,6 +108,13 @@ internal class WebSocketConnection(
|
|||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun close() {
|
fun close() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
alarmManagerCallback?.run(alarmManager::cancel)
|
||||||
|
alarmManagerCallback = null
|
||||||
|
} else {
|
||||||
|
handlerCallback?.run(reconnectHandler::removeCallbacks)
|
||||||
|
handlerCallback = null
|
||||||
|
}
|
||||||
if (webSocket != null) {
|
if (webSocket != null) {
|
||||||
webSocket?.close(1000, "")
|
webSocket?.close(1000, "")
|
||||||
closed()
|
closed()
|
||||||
@@ -119,8 +128,10 @@ internal class WebSocketConnection(
|
|||||||
state = State.Disconnected
|
state = State.Disconnected
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun scheduleReconnectNow(seconds: Long) = scheduleReconnect(ID.get(), seconds)
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
fun scheduleReconnect(seconds: Long) {
|
fun scheduleReconnect(id: Long, seconds: Long) {
|
||||||
if (state == State.Connecting || state == State.Connected) {
|
if (state == State.Connecting || state == State.Connected) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -130,17 +141,23 @@ internal class WebSocketConnection(
|
|||||||
Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
|
Logger.info("WebSocket: scheduling a restart in $seconds second(s) (via alarm manager)")
|
||||||
val future = Calendar.getInstance()
|
val future = Calendar.getInstance()
|
||||||
future.add(Calendar.SECOND, seconds.toInt())
|
future.add(Calendar.SECOND, seconds.toInt())
|
||||||
|
|
||||||
|
alarmManagerCallback?.run(alarmManager::cancel)
|
||||||
|
val cb = OnAlarmListener { syncExec(id) { start() } }
|
||||||
|
alarmManagerCallback = cb
|
||||||
alarmManager.setExact(
|
alarmManager.setExact(
|
||||||
AlarmManager.RTC_WAKEUP,
|
AlarmManager.RTC_WAKEUP,
|
||||||
future.timeInMillis,
|
future.timeInMillis,
|
||||||
"reconnect-tag",
|
"reconnect-tag",
|
||||||
{ start() },
|
cb,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
Logger.info("WebSocket: scheduling a restart in $seconds second(s)")
|
Logger.info("WebSocket: scheduling a restart in $seconds second(s)")
|
||||||
reconnectHandler.removeCallbacks(reconnectCallback)
|
handlerCallback?.run(reconnectHandler::removeCallbacks)
|
||||||
reconnectHandler.postDelayed(reconnectCallback, TimeUnit.SECONDS.toMillis(seconds))
|
val cb = Runnable { syncExec(id) { start() } }
|
||||||
|
handlerCallback = cb
|
||||||
|
reconnectHandler.postDelayed(cb, TimeUnit.SECONDS.toMillis(seconds))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +207,7 @@ internal class WebSocketConnection(
|
|||||||
val minutes = (errorCount * 2 - 1).coerceAtMost(20)
|
val minutes = (errorCount * 2 - 1).coerceAtMost(20)
|
||||||
|
|
||||||
onFailure.execute(response?.message ?: "unreachable", minutes)
|
onFailure.execute(response?.message ?: "unreachable", minutes)
|
||||||
scheduleReconnect(TimeUnit.MINUTES.toSeconds(minutes.toLong()))
|
scheduleReconnect(id, TimeUnit.MINUTES.toSeconds(minutes.toLong()))
|
||||||
}
|
}
|
||||||
super.onFailure(webSocket, t, response)
|
super.onFailure(webSocket, t, response)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,10 +172,7 @@ internal class WebSocketService : Service() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doReconnect() {
|
private fun doReconnect() {
|
||||||
if (connection == null) {
|
connection?.scheduleReconnectNow(15)
|
||||||
return
|
|
||||||
}
|
|
||||||
connection!!.scheduleReconnect(15)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onFailure(status: String, minutes: Int) {
|
private fun onFailure(status: String, minutes: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user