Untested: WS battery improvement, relates to #113 and binwiederhier/ntfy#1662
This commit is contained in:
parent
7bb812662e
commit
3e93a3fb8d
2 changed files with 27 additions and 3 deletions
|
|
@ -10,6 +10,7 @@ import io.heckel.ntfy.util.Log
|
|||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class Application : Application() {
|
||||
val ioScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
|
||||
|
|
@ -34,8 +35,19 @@ class Application : Application() {
|
|||
val connectivityManager = getSystemService(CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
connectivityManager.registerDefaultNetworkCallback(object : ConnectivityManager.NetworkCallback() {
|
||||
override fun onAvailable(network: Network) {
|
||||
// Force reconnect of all WebSocket/JSON connections so they're rebound to the new
|
||||
// default network. This catches Wi-Fi <-> cellular handoffs and similar transitions
|
||||
// where the underlying socket is bound to a network that's no longer the default.
|
||||
// Without this, broken connections would only be detected via the (potentially
|
||||
// long) ping/pong timeout.
|
||||
ioScope.launch {
|
||||
repository.getSubscriptions()
|
||||
.map { it.baseUrl }
|
||||
.distinct()
|
||||
.forEach { repository.incrementConnectionForceReconnectVersion(it) }
|
||||
SubscriberServiceManager.refresh(this@Application)
|
||||
}
|
||||
}
|
||||
override fun onLost(network: Network) {
|
||||
SubscriberServiceManager.refresh(this@Application)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,12 +46,24 @@ object HttpUtil {
|
|||
|
||||
/**
|
||||
* Client for WebSocket connections.
|
||||
* No read timeout, 1 minute ping interval, 10s connect timeout.
|
||||
* No read timeout, 5 minute ping interval, 10s connect timeout.
|
||||
*
|
||||
* Dead connections are normally caught by one of two faster mechanisms:
|
||||
* 1. Device-side network changes (Wi-Fi <-> cellular, network drop/return) are
|
||||
* detected instantly by Application.registerNetworkCallback's onAvailable
|
||||
* handler, which bumps connectionForceReconnectVersion to force a reconnect.
|
||||
* 2. Server-side failures (crash, restart, server's own pong timeout) surface as
|
||||
* TCP FIN/RST and are detected instantly via OkHttp's onClosed/onFailure.
|
||||
*
|
||||
* The 5-minute client ping is only a fallback for the rare case where neither of
|
||||
* the above fires: silent server hangs, NAT eviction, asymmetric routing breaks, etc.
|
||||
* We use a long interval so the modem can fully power down between pings, which is
|
||||
* the dominant battery factor for the foreground service.
|
||||
*/
|
||||
suspend fun wsClient(context: Context, baseUrl: String): OkHttpClient {
|
||||
return emptyClientBuilder(context, baseUrl)
|
||||
.readTimeout(0, TimeUnit.MILLISECONDS)
|
||||
.pingInterval(1, TimeUnit.MINUTES) // Technically not necessary, the server also pings us
|
||||
.pingInterval(5, TimeUnit.MINUTES)
|
||||
.connectTimeout(10, TimeUnit.SECONDS)
|
||||
.build()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue