refactor(dm): 채팅 화면 전송을 WebSocket으로 전환한다
This commit is contained in:
@@ -52,7 +52,7 @@ class DmChatRoomActivity : BaseActivity<ActivityDmChatRoomBinding>(
|
||||
|
||||
override fun onStop() {
|
||||
isStarted = false
|
||||
viewModel.disconnectRealtime()
|
||||
viewModel.leaveRealtime()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ import kr.co.vividnext.sodalive.base.BaseViewModel
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import kr.co.vividnext.sodalive.common.SharedPreferenceManager
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.CreateDmChatRoomResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatEventClient
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatMessageResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatMessagesPageResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatRepository
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatRoomOpenResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.SendDmChatMessageResponse
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatSocketClient
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.data.DmChatSocketEvent
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.model.DmChatMessageStatus
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.model.DmChatMessageUiItem
|
||||
import kr.co.vividnext.sodalive.v2.main.chat.dm.model.DmChatRoomUiState
|
||||
@@ -46,7 +46,6 @@ class DmChatRoomViewModel(
|
||||
private var shouldReconnectRealtime: Boolean = false
|
||||
private var currentAuthToken: String = ""
|
||||
private var currentRealtimeToken: String = ""
|
||||
private var isDisconnecting: Boolean = false
|
||||
private var reconnectDisposable: Disposable? = null
|
||||
private var localMessageSequence: Long = 0L
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
@@ -187,16 +186,11 @@ class DmChatRoomViewModel(
|
||||
shouldReconnectRealtime = true
|
||||
reconnectDisposable?.dispose()
|
||||
reconnectDisposable = null
|
||||
repository.connectRealtime(
|
||||
repository.connectSocket(
|
||||
token = token,
|
||||
roomId = roomId,
|
||||
listener = object : DmChatEventClient.Listener {
|
||||
override fun onConnected() {
|
||||
scheduleRealtimeCallback { syncLatestMessagesAfterReconnect(token = token) }
|
||||
}
|
||||
|
||||
override fun onMessage(message: DmChatMessageResponse) {
|
||||
scheduleRealtimeCallback { onRealtimeMessage(message) }
|
||||
listener = object : DmChatSocketClient.Listener {
|
||||
override fun onEvent(event: DmChatSocketEvent) {
|
||||
scheduleRealtimeCallback { handleSocketEvent(event, token) }
|
||||
}
|
||||
|
||||
override fun onFailure(throwable: Throwable) {
|
||||
@@ -208,9 +202,10 @@ class DmChatRoomViewModel(
|
||||
}
|
||||
}
|
||||
)
|
||||
repository.sendJoinRoom(roomId)
|
||||
}
|
||||
|
||||
fun disconnectRealtime() {
|
||||
fun leaveRealtime() {
|
||||
val roomId = currentRoomId
|
||||
if (roomId <= 0L) return
|
||||
|
||||
@@ -219,22 +214,8 @@ class DmChatRoomViewModel(
|
||||
isRealtimeConnected = false
|
||||
reconnectDisposable?.dispose()
|
||||
reconnectDisposable = null
|
||||
repository.cancelRealtime()
|
||||
if (isDisconnecting) return
|
||||
|
||||
isDisconnecting = true
|
||||
compositeDisposable.add(
|
||||
repository.disconnectRealtime(token = authToken(), roomId = roomId)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ isDisconnecting = false },
|
||||
{
|
||||
isDisconnecting = false
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
}
|
||||
)
|
||||
)
|
||||
repository.sendLeaveRoom(roomId)
|
||||
repository.closeSocket()
|
||||
}
|
||||
|
||||
private fun scheduleRealtimeReconnect() {
|
||||
@@ -266,7 +247,7 @@ class DmChatRoomViewModel(
|
||||
mainHandler.removeCallbacksAndMessages(null)
|
||||
reconnectDisposable?.dispose()
|
||||
reconnectDisposable = null
|
||||
repository.cancelRealtime()
|
||||
repository.closeSocket()
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
@@ -302,22 +283,12 @@ class DmChatRoomViewModel(
|
||||
}
|
||||
|
||||
private fun sendLocalMessage(localId: String, text: String) {
|
||||
compositeDisposable.add(
|
||||
repository.sendTextMessage(
|
||||
token = authToken(),
|
||||
roomId = currentRoomId,
|
||||
textMessage = text
|
||||
)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
{ handleSendResult(localId, it) },
|
||||
{
|
||||
it.message?.let { message -> Logger.e(message) }
|
||||
markLocalMessageFailed(localId)
|
||||
}
|
||||
)
|
||||
val sent = repository.sendSocketText(
|
||||
roomId = currentRoomId,
|
||||
requestId = localId,
|
||||
textMessage = text
|
||||
)
|
||||
if (!sent) markLocalMessageFailed(localId)
|
||||
}
|
||||
|
||||
private fun handleOpenRoomResult(response: ApiResponse<DmChatRoomOpenResponse>) {
|
||||
@@ -356,12 +327,18 @@ class DmChatRoomViewModel(
|
||||
emitContent()
|
||||
}
|
||||
|
||||
private fun handleSendResult(
|
||||
localId: String,
|
||||
response: ApiResponse<SendDmChatMessageResponse>
|
||||
) {
|
||||
val message = response.data?.message
|
||||
val sentItem = if (response.success && message != null) message.toUiItem() else null
|
||||
private fun handleSocketEvent(event: DmChatSocketEvent, token: String) {
|
||||
when (event) {
|
||||
DmChatSocketEvent.Joined -> syncLatestMessagesAfterReconnect(token = token)
|
||||
is DmChatSocketEvent.Message -> onRealtimeMessage(event.message)
|
||||
is DmChatSocketEvent.SendAck -> handleSendAck(event.requestId, event.message)
|
||||
is DmChatSocketEvent.Error -> event.requestId?.let { markLocalMessageFailed(it) }
|
||||
DmChatSocketEvent.Pong -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleSendAck(localId: String, message: DmChatMessageResponse) {
|
||||
val sentItem = message.toUiItem()
|
||||
if (sentItem == null) {
|
||||
markLocalMessageFailed(localId)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user