From 88933fba8d17ae255bc13589ac63192014beb723 Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Fri, 15 Aug 2025 18:07:12 -0400 Subject: [PATCH] Fixes the time to reconnect interval due to an error between seconds and milliseconds. --- .../client/single/basic/BasicRelayClient.kt | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt index b16d35f8a..54c1f7e5e 100644 --- a/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt +++ b/quartz/src/main/java/com/vitorpamplona/quartz/nip01Core/relay/client/single/basic/BasicRelayClient.kt @@ -26,7 +26,6 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.IRelayClientListener import com.vitorpamplona.quartz.nip01Core.relay.client.listeners.RelayState import com.vitorpamplona.quartz.nip01Core.relay.client.single.IRelayClient -import com.vitorpamplona.quartz.nip01Core.relay.client.single.basic.BasicRelayClient.Companion.DELAY_TO_RECONNECT_IN_MSECS import com.vitorpamplona.quartz.nip01Core.relay.client.stats.RelayStat import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.AuthMessage import com.vitorpamplona.quartz.nip01Core.relay.commands.toClient.ClosedMessage @@ -84,7 +83,7 @@ open class BasicRelayClient( ) : IRelayClient { companion object { // waits 3 minutes to reconnect once things fail - const val DELAY_TO_RECONNECT_IN_MSECS = 500L + const val DELAY_TO_RECONNECT_IN_SECS = 1 const val EVENT_MESSAGE_PREFIX = "[\"${EventMessage.LABEL}\"" } @@ -94,8 +93,8 @@ open class BasicRelayClient( private var isReady: Boolean = false private var usingCompression: Boolean = false - private var lastConnectTentative: Long = 0L // the beginning of time. - private var delayToConnect = DELAY_TO_RECONNECT_IN_MSECS + private var lastConnectTentativeInSeconds: Long = 0L // the beginning of time. + private var delayToConnectInSeconds = DELAY_TO_RECONNECT_IN_SECS private var afterEOSEPerSubscription = mutableMapOf() @@ -138,7 +137,7 @@ open class BasicRelayClient( Log.d(logTag, "Connecting...") - lastConnectTentative = TimeUtils.now() + lastConnectTentativeInSeconds = TimeUtils.now() socket = socketBuilder.build(url, MyWebsocketListener(onConnected)) socket?.connect() @@ -210,18 +209,27 @@ open class BasicRelayClient( // socket is already closed // socket?.disconnect() - // checks if this is an actual failure. Closing the socket generates an onFailure as well. - if (!(socket == null && (t.message == "Socket is closed" || t.message == "Socket closed"))) { - stats.newError(response ?: t.message ?: "onFailure event from server: ${t.javaClass.simpleName}") + if (socket == null) { + // comes from the disconnect action. + listener.onRelayStateChange(this@BasicRelayClient, RelayState.DISCONNECTED) + } else { + // checks if this is an actual failure. Closing the socket generates an onFailure as well. + if (!(socket == null && (t.message == "Socket is closed" || t.message == "Socket closed"))) { + stats.newError(response ?: t.message ?: "onFailure event from server: ${t.javaClass.simpleName}") + } + + // Failures disconnect the relay. + markConnectionAsClosed() + + Log.w(logTag, "OnFailure $code $response ${t.message}") + + if (code == 403 || code == 502 || code == 503 || code == 402 || code == 410 || t.message == "SOCKS: Host unreachable") { + dontTryAgainForALongTime() + } + + listener.onRelayStateChange(this@BasicRelayClient, RelayState.DISCONNECTED) + listener.onError(this@BasicRelayClient, "", Error("WebSocket Failure. Response: $code $response. Exception: ${t.message}", t)) } - - // Failures disconnect the relay. - markConnectionAsClosed() - - Log.w(logTag, "OnFailure $code $response ${t.message} $socket") - - listener.onRelayStateChange(this@BasicRelayClient, RelayState.DISCONNECTED) - listener.onError(this@BasicRelayClient, "", Error("WebSocket Failure. Response: $code $response. Exception: ${t.message}", t)) } } @@ -260,7 +268,7 @@ open class BasicRelayClient( this.usingCompression = usingCompression // resets any extra delays added during on offline state - this.delayToConnect = DELAY_TO_RECONNECT_IN_MSECS + this.delayToConnectInSeconds = DELAY_TO_RECONNECT_IN_SECS stats.pingInMs = pingInMs } @@ -343,8 +351,8 @@ open class BasicRelayClient( override fun disconnect() { Log.d(logTag, "Disconnecting...") - lastConnectTentative = 0L // this is not an error, so prepare to reconnect as soon as requested. - delayToConnect = DELAY_TO_RECONNECT_IN_MSECS + lastConnectTentativeInSeconds = 0L // this is not an error, so prepare to reconnect as soon as requested. + delayToConnectInSeconds = DELAY_TO_RECONNECT_IN_SECS socket?.disconnect() socket = null isReady = false @@ -371,12 +379,7 @@ open class BasicRelayClient( } } } else { - // waits 60 seconds to reconnect after disconnected. - if (TimeUtils.now() > lastConnectTentative + delayToConnect) { - delayToConnect = delayToConnect * 2 - // sends all filters after connection is successful. - connect() - } + connectAndSyncFiltersIfDisconnected() } } @@ -392,25 +395,30 @@ open class BasicRelayClient( } } } else { + connectAndSyncFiltersIfDisconnected() + } + } + + override fun connectAndSyncFiltersIfDisconnected() { + if (!isConnectionStarted() && !connectingMutex.get()) { // waits 60 seconds to reconnect after disconnected. - if (TimeUtils.now() > lastConnectTentative + delayToConnect) { - // sends all filters after connection is successful. - delayToConnect = delayToConnect * 2 + if (TimeUtils.now() > lastConnectTentativeInSeconds + delayToConnectInSeconds) { + upRelayDelayToConnect() connect() } } } - override fun connectAndSyncFiltersIfDisconnected() { - if (socket == null) { - // waits 60 seconds to reconnect after disconnected. - if (TimeUtils.now() > lastConnectTentative + delayToConnect) { - delayToConnect = delayToConnect * 2 - connect() - } + fun upRelayDelayToConnect() { + if (delayToConnectInSeconds < TimeUtils.FIVE_MINUTES) { + delayToConnectInSeconds = delayToConnectInSeconds * 2 } } + fun dontTryAgainForALongTime() { + delayToConnectInSeconds = TimeUtils.ONE_DAY + } + override fun send(event: Event) { listener.onBeforeSend(this@BasicRelayClient, event)