feat(chat): DM SSE 재연결 기반을 추가한다
This commit is contained in:
@@ -49,11 +49,21 @@ class DmChatEventParser(private val gson: Gson) {
|
||||
}
|
||||
}
|
||||
|
||||
interface DmChatRealtimeClient {
|
||||
fun connect(
|
||||
token: String,
|
||||
roomId: Long,
|
||||
listener: DmChatEventClient.Listener
|
||||
)
|
||||
|
||||
fun cancel()
|
||||
}
|
||||
|
||||
class DmChatEventClient(
|
||||
private val okHttpClient: OkHttpClient,
|
||||
gson: Gson,
|
||||
private val baseUrl: String
|
||||
) {
|
||||
) : DmChatRealtimeClient {
|
||||
interface Listener {
|
||||
fun onConnected()
|
||||
fun onMessage(message: DmChatMessageResponse)
|
||||
@@ -67,7 +77,7 @@ class DmChatEventClient(
|
||||
private var listener: Listener? = null
|
||||
|
||||
@Synchronized
|
||||
fun connect(
|
||||
override fun connect(
|
||||
token: String,
|
||||
roomId: Long,
|
||||
listener: Listener
|
||||
@@ -105,7 +115,7 @@ class DmChatEventClient(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun cancel() {
|
||||
override fun cancel() {
|
||||
call?.cancel()
|
||||
call = null
|
||||
listener = null
|
||||
@@ -115,7 +125,12 @@ class DmChatEventClient(
|
||||
reader.use { bufferedReader ->
|
||||
val frame = StringBuilder()
|
||||
while (!call.isCanceled()) {
|
||||
val line = bufferedReader.readLine() ?: break
|
||||
val line = bufferedReader.readLine()
|
||||
if (line == null) {
|
||||
if (frame.isNotEmpty()) dispatch(frame.toString())
|
||||
notifyStreamClosed(call)
|
||||
return
|
||||
}
|
||||
if (line.isBlank()) {
|
||||
dispatch(frame.toString())
|
||||
frame.clear()
|
||||
@@ -123,10 +138,13 @@ class DmChatEventClient(
|
||||
frame.append(line).append('\n')
|
||||
}
|
||||
}
|
||||
if (frame.isNotEmpty()) dispatch(frame.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyStreamClosed(call: Call) {
|
||||
if (!call.isCanceled()) listener?.onFailure(IOException("SSE stream closed"))
|
||||
}
|
||||
|
||||
private fun dispatch(frame: String) {
|
||||
when (val event = parser.parse(frame)) {
|
||||
DmChatEventParser.Event.Connected -> listener?.onConnected()
|
||||
|
||||
@@ -3,7 +3,10 @@ package kr.co.vividnext.sodalive.v2.main.chat.dm.data
|
||||
import io.reactivex.rxjava3.core.Single
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
|
||||
class DmChatRepository(private val api: DmChatApi) {
|
||||
class DmChatRepository(
|
||||
private val api: DmChatApi,
|
||||
private val realtimeClient: DmChatRealtimeClient? = null
|
||||
) {
|
||||
fun createOrGetRoom(
|
||||
token: String,
|
||||
creatorId: Long
|
||||
@@ -52,6 +55,18 @@ class DmChatRepository(private val api: DmChatApi) {
|
||||
roomId = roomId
|
||||
)
|
||||
|
||||
fun connectRealtime(
|
||||
token: String,
|
||||
roomId: Long,
|
||||
listener: DmChatEventClient.Listener
|
||||
) {
|
||||
realtimeClient?.connect(token = token, roomId = roomId, listener = listener)
|
||||
}
|
||||
|
||||
fun cancelRealtime() {
|
||||
realtimeClient?.cancel()
|
||||
}
|
||||
|
||||
private fun bearer(token: String) = "Bearer $token"
|
||||
|
||||
private companion object {
|
||||
|
||||
Reference in New Issue
Block a user