Amazon IVS Chat Client Messaging - Android - Execute connect method in onResume won't bring the connection back after disconnect execution in onPause

0

I'm building an Android app with chat functionalities using Amazon IVS Chat Client Messaging SDK and I stucked with handling lifecycle of the chat room and web socket connection.

According to the documentation Disconnect from a Chat Room:

Because the WebSocket connection will stop working after a short time when the application is in a background state, we recommend that you manually connect/disconnect when transitioning from/to a background state. To do so, match the room.connect() call in the onResume() lifecycle method, on Android Activity or Fragment, with a room.disconnect() call in the onPause() lifecycle method.

So I implemented that way, but I never get connected state back again (I need to close activity and open it again, then all works fine):

🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Changed state: DISCONNECTED -> CONNECTING
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Calling onConnecting
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Requesting token
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Did receive token: ChatToken(token=CHAT_TOKEN_HERE#1, sessionExpirationTime=Fri Sep 08 13:20:24 GMT+02:00 2023, tokenExpirationTime=Fri Sep 08 13:20:24 GMT+02:00 2023)
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Connecting to web socket wss://edge.ivschat.us-east-1.amazonaws.com
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTED) Changed state: CONNECTING -> CONNECTED
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTED) Calling onConnected
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTED) Connected
// App moves to ON_PAUSE state
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (DISCONNECTED) Changed state: CONNECTED -> DISCONNECTED
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (DISCONNECTED) Calling onDisconnected
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (DISCONNECTED) Did receive socket onClosing event: disconnect reason CLIENT_DISCONNECT, socket code 1000, socket reason: 
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (DISCONNECTED) Reconnect not needed: disconnect reason CLIENT_DISCONNECT
// APP moves to ON_RESUME state
🟢 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Changed state: DISCONNECTED -> CONNECTING
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Calling onConnecting
🟤 Room 58a2b001-7c9c-4c2b-935b-ef07e74cc2c3 (CONNECTING) Requesting token

I keep seeing Requesting token. For the demo app I found here, I noticed that you didn't execute disconnect method explicitly when app lifecycle changes state to Pause/Stop. Was it implemented on purpose?

Please take a look on implementation of wrapper for ChatRoom class. Did I miss something?.:

internal class ChatRemoteApiImpl @Inject constructor(
    private val webinarRemoteApi: WebinarRemoteApi,
    private val chatClientStateMapper: ChatClientStateMapper,
    private val chatMessageRemoteMapper: ChatMessageRemoteMapper,
) : ChatRemoteApi {

    private var _chatRoom: ChatRoom? = null
        set(value) {
            field = value
            if (value != null) {
                mutableChatRoomFlow.tryEmit(value)
            }
        }

    private val isConnected: Boolean
        get() {
            return chatRoom.state == ChatRoom.State.CONNECTED
        }

    private val mutableChatRoomFlow = bufferedFlow<ChatRoom>(replay = 1)

    private val chatRoom: ChatRoom
        get() {
            return checkNotNull(_chatRoom) { "Chat Room need to be initialized" }
        }

    override val stateChange: Flow<State>
        get() = mutableChatRoomFlow.take(1)
            .flatMapLatest { chatRoom ->
                chatRoom.stateChanges()
                    .map(chatClientStateMapper::map)
            }

    override val messages: Flow<ChatMessageResponse>
        get() = mutableChatRoomFlow.take(1)
            .flatMapLatest { chatRoom ->
                chatRoom.receivedMessages()
                    .map(chatMessageRemoteMapper::map)
            }

    override suspend fun createClient(params: ChatClientParams) {
        val chatTokenProvider: suspend () -> ChatToken = suspend {
            val response = webinarRemoteApi.createChatToken(params.webinarId, params.userId)
            with(response) {
                ChatToken(
                    token,
                    tokenExpirationTime.toDate(),
                    sessionExpirationTime.toDate(),
                )
            }
        }

        _chatRoom = ChatRoom(
            regionOrUrl = params.region,
            tokenProvider = chatTokenProvider,
        )
    }

    override fun connect() {       // call onResume
        if (!isConnected) {
            chatRoom.connect()
        }
    }

    override fun disconnect() {   // call onPause
        chatRoom.disconnect()
    }
}

I see two solutions:

  1. Never call disconnect, just keep the connection no matter of lifecycle. (Only disconnect before killing the activity). - But from the documentation I see that if app stays in background for long time then the socket connection stops. So that solution may not work well.
  2. Second options is to re-create new chat room every time the app comes back from background.
gefragt vor 8 Monaten96 Aufrufe
Keine Antworten

Du bist nicht angemeldet. Anmelden um eine Antwort zu veröffentlichen.

Eine gute Antwort beantwortet die Frage klar, gibt konstruktives Feedback und fördert die berufliche Weiterentwicklung des Fragenstellers.

Richtlinien für die Beantwortung von Fragen