diff --git a/core/data/src/main/java/com/idle/data/repository/chatting/ChattingRepositoryImpl.kt b/core/data/src/main/java/com/idle/data/repository/chatting/ChattingRepositoryImpl.kt index d2bada36..fcef22ba 100644 --- a/core/data/src/main/java/com/idle/data/repository/chatting/ChattingRepositoryImpl.kt +++ b/core/data/src/main/java/com/idle/data/repository/chatting/ChattingRepositoryImpl.kt @@ -17,7 +17,7 @@ class ChattingRepositoryImpl @Inject constructor( webSocketDataSource.disconnectWebSocket() override fun subscribeChatMessage(): Flow = - webSocketDataSource.getChatMessageFlow() + webSocketDataSource.chatMessageFlow .filterNotNull() .map { it.toVO() } -} \ No newline at end of file +} diff --git a/core/network/src/main/java/com/idle/network/source/websocket/WebSocketDataSource.kt b/core/network/src/main/java/com/idle/network/source/websocket/WebSocketDataSource.kt index 0039eb42..733c241b 100644 --- a/core/network/src/main/java/com/idle/network/source/websocket/WebSocketDataSource.kt +++ b/core/network/src/main/java/com/idle/network/source/websocket/WebSocketDataSource.kt @@ -3,23 +3,29 @@ package com.idle.network.source.websocket import com.idle.network.BuildConfig import com.idle.network.di.WebSocketOkHttpClient import com.idle.network.model.chatting.ChatMessageResponse +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.withContext import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.WebSocket import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.pow @Singleton class WebSocketDataSource @Inject constructor( @WebSocketOkHttpClient private val client: OkHttpClient, private val chatMessageListener: ChatMessageListener, ) { + val chatMessageFlow: StateFlow = chatMessageListener.chatMessageFlow + private lateinit var chatMessageWebSocket: WebSocket private var connectionAttempts = 0 - fun connectWebSocket(): Result { - return try { + suspend fun connectWebSocket(): Result = withContext(Dispatchers.IO) { + try { val chatMessageRequest: Request = Request.Builder() .url(BuildConfig.CARE_WEBSOCKET_URL) .build() @@ -29,6 +35,8 @@ class WebSocketDataSource @Inject constructor( Result.success(Unit) } catch (e: Exception) { if (connectionAttempts < MAX_RETRY_ATTEMPTS) { + val waitTime = minOf(calculateBackoffTime(connectionAttempts), MAX_WAIT_TIME) + delay(waitTime) connectionAttempts++ connectWebSocket() } else { @@ -48,9 +56,11 @@ class WebSocketDataSource @Inject constructor( } } - fun getChatMessageFlow(): StateFlow = chatMessageListener.chatMessageFlow + private fun calculateBackoffTime(attempt: Int): Long = + (2.0.pow(attempt) * 1000).toLong() companion object { private const val MAX_RETRY_ATTEMPTS = 5 + private const val MAX_WAIT_TIME = 10_000L // 10 seconds } }