Fix Ping/Pong (de)serialization and response

This commit is contained in:
sim 2024-12-29 20:42:15 +00:00
parent 117c3f1041
commit 3986cb916f
5 changed files with 44 additions and 9 deletions

View file

@ -30,6 +30,11 @@ object MessageSender {
}
}
fun ping(context: Context) {
send(context, ClientMessage.Ping)
ServerConnection.waitingPong.set(true)
}
fun hasPendingMsgs(): Boolean {
return messageQueue.isNotEmpty()
}

View file

@ -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)
}
}

View file

@ -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<ClientMessage>(this))
return when (this) {
Ping -> "{}"
else -> json.encodeToString<ClientMessage>(this)
}
}
fun send(ws: WebSocket) {
ws.send(this.serialize())
}
}

View file

@ -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<ServerMessage>(jsonStr)
} catch (e: SerializationException) {
if (json.decodeFromString<Map<String, String>>(jsonStr).isEmpty()) {
Ping
} else {
null
}
}
}
}
}

View file

@ -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")