@@ -3,23 +3,29 @@ package com.idle.network.source.websocket
33import com.idle.network.BuildConfig
44import com.idle.network.di.WebSocketOkHttpClient
55import com.idle.network.model.chatting.ChatMessageResponse
6+ import kotlinx.coroutines.Dispatchers
7+ import kotlinx.coroutines.delay
68import kotlinx.coroutines.flow.StateFlow
9+ import kotlinx.coroutines.withContext
710import okhttp3.OkHttpClient
811import okhttp3.Request
912import okhttp3.WebSocket
1013import javax.inject.Inject
1114import javax.inject.Singleton
15+ import kotlin.math.pow
1216
1317@Singleton
1418class WebSocketDataSource @Inject constructor(
1519 @WebSocketOkHttpClient private val client : OkHttpClient ,
1620 private val chatMessageListener : ChatMessageListener ,
1721) {
22+ val chatMessageFlow: StateFlow <ChatMessageResponse ?> = chatMessageListener.chatMessageFlow
23+
1824 private lateinit var chatMessageWebSocket: WebSocket
1925 private var connectionAttempts = 0
2026
21- fun connectWebSocket (): Result <Unit > {
22- return try {
27+ suspend fun connectWebSocket (): Result <Unit > = withContext( Dispatchers . IO ) {
28+ try {
2329 val chatMessageRequest: Request = Request .Builder ()
2430 .url(BuildConfig .CARE_WEBSOCKET_URL )
2531 .build()
@@ -29,6 +35,8 @@ class WebSocketDataSource @Inject constructor(
2935 Result .success(Unit )
3036 } catch (e: Exception ) {
3137 if (connectionAttempts < MAX_RETRY_ATTEMPTS ) {
38+ val waitTime = minOf(calculateBackoffTime(connectionAttempts), MAX_WAIT_TIME )
39+ delay(waitTime)
3240 connectionAttempts++
3341 connectWebSocket()
3442 } else {
@@ -48,9 +56,11 @@ class WebSocketDataSource @Inject constructor(
4856 }
4957 }
5058
51- fun getChatMessageFlow (): StateFlow <ChatMessageResponse ?> = chatMessageListener.chatMessageFlow
59+ private fun calculateBackoffTime (attempt : Int ): Long =
60+ (2.0 .pow(attempt) * 1000 ).toLong()
5261
5362 companion object {
5463 private const val MAX_RETRY_ATTEMPTS = 5
64+ private const val MAX_WAIT_TIME = 10_000L // 10 seconds
5565 }
5666}
0 commit comments