在应用程序生命周期Android上保持套接字连接打开

Posted

技术标签:

【中文标题】在应用程序生命周期Android上保持套接字连接打开【英文标题】:Keep socket connection open on application lifecycle Android 【发布时间】:2020-10-17 11:02:54 【问题描述】:

我想在我的应用程序处于前台时打开一个套接字。我从这里使用 JAVA Api WebSocketClient:

所以我创建了一个管理器,它使用 onOpen、onClose、onMessage 和 onError 回调实现 WebSocketClient 接口,如下所示。 我还有一个 pingPongTimer,所以我可以每隔 10 秒检查一次连接。 该过程的循环在应用程序生命周期中绑定,因此当应用程序进入前台时,我调用connect and startPingPongTimer 方法,而当它进入后台时,我调用kill and stopPingPongTimer 方法。 WSS url 是来自 Amazon Web Services 的 webSocket。 我的问题是有时我调用 connect 方法,但我从来没有得到 onOpen 回调。我有时也会在断开连接并重新连接后收到 onClose 回调,因此我无法处理当前连接,因为我从前一个连接中获得了 onClose。

class FlowSocketManagerImpl: FlowSocketManager 

    private var isFlowing: Boolean = false
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    private var pingPongTimer = object: CountDownTimer(10000, 1000) 
        override fun onTick(millisUntilFinished: Long) 

        override fun onFinish() 
            println("On Finish")
            send("Hello")
            this.start()
        
    

    private val mWebSocketClient = object : WebSocketClient(URI(Wss)) 
        override fun onOpen(serverHandshake: ServerHandshake?) 
            println("onOpen")
            isFlowing = true
           
        

        override fun onMessage(envelope: String?) 
            println("onMessage $envelope")
        

        override fun onClose(code: Int, reason: String, remote: Boolean) 
            println("onClose $code $reason $remote")
            isFlowing = false
            socketBackOffStrategy(code)
        

        override fun onError(e: Exception) 
            e.printStackTrace()
            println("onError $e.message")
            isFlowing = false
        
    

    @Throws(Exception::class)
    override fun connect() 
        mWebSocketClient.close()
        mWebSocketClient.connectionLostTimeout = 10
        if (mWebSocketClient.isClosed)
            mWebSocketClient.connect()
    

    override fun send(envelope: String) 
        try 
            mWebSocketClient.send(envelope)
         catch (e: WebsocketNotConnectedException) 
            // ToDo Mark as unread
            println("No connection")
        
    

    override fun kill() 
        if (mWebSocketClient.isOpen) 
            mWebSocketClient.close()
        
    

    private fun socketBackOffStrategy(code: Int) 
        when (code) 
            -1 -> 
                // NetWork Unavailable
                scope.launch 
                    delay(10000)
                    withContext(Dispatchers.Main) 
                        connect()
                    
                
            
            1000 -> 
                // Successfully disconnected
            
            1006 -> 
                // 1006 The connection was closed because the other endpoint did not respond with a pong in time.
                // For more information check: https://github.com/TooTallNate/Java-WebSocket/wiki/Lost-connection-detection
                if (mWebSocketClient.isClosed)
                    connect()
            
        
    

    override fun startPingPongCountDown() 
        pingPongTimer.start()
    

    override fun stopPingPongCountDown() 
        pingPongTimer.cancel()
    


什么是用于我的目的的最佳方式或库,或者我怎样才能使它更可靠、高效和稳定? 谢谢

【问题讨论】:

【参考方案1】:

经过大量搜索,我找到了一个可以自行完成所有工作的库。 它被称为 Scarlet,由 Tinder 开发。 https://github.com/Tinder/Scarlet

【讨论】:

以上是关于在应用程序生命周期Android上保持套接字连接打开的主要内容,如果未能解决你的问题,请参考以下文章

Sailsjs:在 Sails 0.11 中,如何不使用带有套接字的 onConnect 生命周期回调

Android生命周期绑定

Android——应用进程和应用生命周期

Android——应用进程和应用生命周期

Android——应用进程和应用生命周期

Android——应用进程和应用生命周期