diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/api/MessageSender.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/api/MessageSender.kt index 6b45bd4..5d3dcf0 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/api/MessageSender.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/api/MessageSender.kt @@ -30,6 +30,11 @@ object MessageSender { } } + fun ping(context: Context) { + send(context, ClientMessage.Ping) + ServerConnection.waitingPong.set(true) + } + fun hasPendingMsgs(): Boolean { return messageQueue.isNotEmpty() } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/api/ServerConnection.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/api/ServerConnection.kt index f17d2a6..58ae852 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/api/ServerConnection.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/api/ServerConnection.kt @@ -8,7 +8,7 @@ import android.util.Log import android.widget.Toast import java.util.Calendar import java.util.concurrent.TimeUnit -import kotlinx.serialization.json.Json +import java.util.concurrent.atomic.AtomicBoolean import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.Response @@ -33,7 +33,6 @@ import org.unifiedpush.distributor.utils.removeSync class ServerConnection(private val context: Context, private val releaseLock: () -> Unit) : WebSocketListener() { - private val json = Json { ignoreUnknownKeys = true } private val store = AppStore(context) fun start(): WebSocket { @@ -73,7 +72,7 @@ class ServerConnection(private val context: Context, private val releaseLock: () is ServerMessage.Broadcast -> ignoreEvent() is ServerMessage.Hello -> onHello(ws, message) is ServerMessage.Notification -> onNotification(ws, message) - ServerMessage.Ping -> onPing() + ServerMessage.Ping -> onPing(ws) is ServerMessage.Register -> onRegister(message) is ServerMessage.Unegister -> onUnregister(message) } @@ -119,8 +118,14 @@ class ServerConnection(private val context: Context, private val releaseLock: () ).send(ws) } - private fun onPing() { + private fun onPing(ws: WebSocket) { FailureCounter.newPing(context) + if (!waitingPong.getAndSet(false)) { + Log.d(TAG, "Sending Pong") + ClientMessage.Ping.send(ws) + } else { + Log.d(TAG, "Received Pong") + } } private fun onRegister(message: ServerMessage.Register) { @@ -201,5 +206,6 @@ class ServerConnection(private val context: Context, private val releaseLock: () companion object { var lastEventDate: Calendar? = null + var waitingPong = AtomicBoolean(false) } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ClientMessage.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ClientMessage.kt index 38380d1..586b57c 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ClientMessage.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ClientMessage.kt @@ -105,8 +105,15 @@ sealed class ClientMessage { @Serializable data class ClientAck(val channelID: String, val version: String) - fun send(ws: WebSocket) { + fun serialize(): String { val json = Json { ignoreUnknownKeys = true } - ws.send(json.encodeToString(this)) + return when (this) { + Ping -> "{}" + else -> json.encodeToString(this) + } + } + + fun send(ws: WebSocket) { + ws.send(this.serialize()) } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ServerMessage.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ServerMessage.kt index 093c155..0c1c0be 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ServerMessage.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/api/data/ServerMessage.kt @@ -3,6 +3,8 @@ package org.unifiedpush.distributor.sunup.api.data import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import kotlinx.serialization.SerializationException +import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonClassDiscriminator @OptIn(ExperimentalSerializationApi::class) @@ -97,4 +99,19 @@ sealed class ServerMessage { @Serializable @SerialName("ping") data object Ping : ServerMessage() + + companion object { + fun deserialize(jsonStr: String): ServerMessage? { + val json = Json { ignoreUnknownKeys = true } + return try { + json.decodeFromString(jsonStr) + } catch (e: SerializationException) { + if (json.decodeFromString>(jsonStr).isEmpty()) { + Ping + } else { + null + } + } + } + } } diff --git a/app/src/main/java/org/unifiedpush/distributor/sunup/services/RestartWorker.kt b/app/src/main/java/org/unifiedpush/distributor/sunup/services/RestartWorker.kt index 764d831..848ebb6 100644 --- a/app/src/main/java/org/unifiedpush/distributor/sunup/services/RestartWorker.kt +++ b/app/src/main/java/org/unifiedpush/distributor/sunup/services/RestartWorker.kt @@ -7,7 +7,6 @@ import android.util.Log import androidx.work.* import org.unifiedpush.distributor.WorkerCompanion import org.unifiedpush.distributor.sunup.api.MessageSender -import org.unifiedpush.distributor.sunup.api.data.ClientMessage import org.unifiedpush.distributor.sunup.callback.NetworkCallbackFactory import org.unifiedpush.distributor.sunup.utils.TAG @@ -20,15 +19,16 @@ class RestartWorker(ctx: Context, params: WorkerParameters) : Worker(ctx, params override fun doWork(): Result { // We avoid running twice at the same time synchronized(lock) { - Log.d(TAG, "Working") + Log.d(TAG, "Working [$id]") if (!NetworkCallbackFactory.hasInternet) { Log.d(TAG, "Aborting, no internet.") return Result.success() } if (FailureCounter.isRunningWithoutFailure) { + Log.d(TAG, "Running without failure") // We send a ping, if it fails it will restart this worker, and wont // pass this check - MessageSender.send(applicationContext, ClientMessage.Ping) + MessageSender.ping(applicationContext) return Result.success() } Log.d(TAG, "Restarting")