Skip to content

Commit 3ca2123

Browse files
committed
feat(kotlin): realtime heartbeat
1 parent 6186686 commit 3ca2123

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

templates/android/library/src/main/java/io/package/services/Realtime.kt.twig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
2929
private companion object {
3030
private const val TYPE_ERROR = "error"
3131
private const val TYPE_EVENT = "event"
32+
private const val TYPE_PONG = "pong"
33+
private const val HEARTBEAT_INTERVAL = 20_000L // 20 seconds
3234

3335
private const val DEBOUNCE_MILLIS = 1L
3436

@@ -40,6 +42,7 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
4042
private var reconnectAttempts = 0
4143
private var subscriptionsCounter = 0
4244
private var reconnect = true
45+
private var heartbeatJob: Job? = null
4346
}
4447

4548
private fun createSocket() {
@@ -80,9 +83,25 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
8083
}
8184

8285
private fun closeSocket() {
86+
stopHeartbeat()
8387
socket?.close(RealtimeCode.POLICY_VIOLATION.value, null)
8488
}
8589

90+
private fun startHeartbeat() {
91+
stopHeartbeat()
92+
heartbeatJob = launch {
93+
while (isActive) {
94+
delay(HEARTBEAT_INTERVAL)
95+
socket?.send("""{"type":"ping"}""")
96+
}
97+
}
98+
}
99+
100+
private fun stopHeartbeat() {
101+
heartbeatJob?.cancel()
102+
heartbeatJob = null
103+
}
104+
86105
private fun getTimeout() = when {
87106
reconnectAttempts < 5 -> 1000L
88107
reconnectAttempts < 15 -> 5000L
@@ -145,6 +164,7 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
145164
override fun onOpen(webSocket: WebSocket, response: Response) {
146165
super.onOpen(webSocket, response)
147166
reconnectAttempts = 0
167+
startHeartbeat()
148168
}
149169

150170
override fun onMessage(webSocket: WebSocket, text: String) {
@@ -181,6 +201,7 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
181201

182202
override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
183203
super.onClosing(webSocket, code, reason)
204+
stopHeartbeat()
184205
if (!reconnect || code == RealtimeCode.POLICY_VIOLATION.value) {
185206
reconnect = true
186207
return
@@ -203,6 +224,7 @@ class Realtime(client: Client) : Service(client), CoroutineScope {
203224

204225
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
205226
super.onFailure(webSocket, t, response)
227+
stopHeartbeat()
206228
t.printStackTrace()
207229
}
208230
}

0 commit comments

Comments
 (0)