Răsfoiți Sursa

feat: 增加PING心跳上报

DoggyZhang 1 săptămână în urmă
părinte
comite
af650d83e8

+ 0 - 144
app/src/main/java/com/adealink/weparty/network/ConnectionStatusManager.kt

@@ -1,144 +0,0 @@
-package com.adealink.weparty.network
-
-import com.adealink.frame.base.fastLazy
-import com.adealink.frame.coroutine.dispatcher.Dispatcher
-import com.adealink.frame.data.collections.ConcurrentList
-import com.adealink.frame.log.Log
-import com.adealink.frame.util.runOnUiThread
-import com.adealink.weparty.commonui.widget.floatview.FloatViewFactory
-import com.adealink.weparty.commonui.widget.floatview.WindowManagerProxy
-import com.adealink.weparty.commonui.widget.floatview.data.FloatWindowType
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.android.asCoroutineDispatcher
-import kotlinx.coroutines.launch
-
-enum class ConnectType {
-    BIZ, //业务长链接
-    IM //IM服务连接(融云)
-}
-
-enum class ConnectStatus {
-    Disconnected, //未连接
-    ConnectingOrConnected; //已连接或者连接中
-
-    fun isDisconnected(): Boolean {
-        return this == Disconnected
-    }
-}
-
-object ConnectionStatusManager : CoroutineScope {
-    private val floatViewFactory by fastLazy { FloatViewFactory() }
-
-    private var connectType2ConnectStatus = hashMapOf<ConnectType, ConnectStatus>()
-    private var connectType2ClickListener = hashMapOf<ConnectType, (() -> Unit)?>()
-    val serialHandler = Dispatcher.getSerialHandler()
-    override val coroutineContext = SupervisorJob() + serialHandler.asCoroutineDispatcher()
-    private val connectStatusListeners = ConcurrentList<ConnectStatusListener>()
-
-    fun addConnectStatusListener(listener: ConnectStatusListener) {
-        connectStatusListeners.add(listener)
-    }
-
-    fun removeConnectStatusListener(listener: ConnectStatusListener) {
-        connectStatusListeners.remove(listener)
-    }
-
-    fun addReconnectClickListener(type: ConnectType, clickListener: (() -> Unit)?) {
-        launch {
-            connectType2ClickListener[type] = clickListener
-        }
-    }
-
-    fun notifyConnectStatus(type: ConnectType, status: ConnectStatus) {
-        launch {
-            Log.i(TAG_DISCONNECT_TIP, "notifyConnectStatus, type:${type}, status:${status}")
-            if (connectType2ConnectStatus[type] == status) {
-                Log.e(
-                    TAG_DISCONNECT_TIP,
-                    "notifyConnectStatus return, status no change. type:${type}, status:${status}"
-                )
-                return@launch
-            }
-            connectType2ConnectStatus[type] = status
-            updateFloatView()
-            runOnUiThread {
-                connectStatusListeners.dispatch { it.onConnectStatusChanged(type, status) }
-            }
-        }
-    }
-
-    /**
-     * 如果业务服务器长链接断开,显示业务服务器长链接断开状态
-     * 如果IM服务断开,显示IM服务断开状态
-     * 如果都没有断开,不显示任何状态
-     */
-    private fun updateFloatView() {
-        val bizConnectStatus = connectType2ConnectStatus[ConnectType.BIZ]
-        val imConnectStatus = connectType2ConnectStatus[ConnectType.IM]
-        Log.i(TAG_DISCONNECT_TIP, "updateFloatView, bizConnectStatus:${bizConnectStatus}, imConnectStatus:${imConnectStatus}")
-        if (bizConnectStatus?.isDisconnected() == true || imConnectStatus?.isDisconnected() == true) {
-            addDisconnectFloatView(bizConnectStatus == ConnectStatus.Disconnected, imConnectStatus == ConnectStatus.Disconnected)
-        } else {
-            removeDisconnectFloatView()
-        }
-    }
-
-    private fun addDisconnectFloatView(bizDisconnected: Boolean, imDisconnected: Boolean) {
-//        runOnUiThread {
-//            if (WindowManagerProxy.getWindowManager().isFloatViewAdded(FloatWindowType.NETWORK_DISCONNECT_TIP)) {
-//                (WindowManagerProxy.getWindowManager().findFloatViewByType(FloatWindowType.NETWORK_DISCONNECT_TIP) as? NetworkReconnectFloatView)?.let {
-//                    Log.i(
-//                        TAG_DISCONNECT_TIP,
-//                        "updateDisconnectFloatView, bizDisconnected:${bizDisconnected}, imDisconnected:${imDisconnected}"
-//                    )
-//                    it.updateWithConnectType(bizDisconnected, imDisconnected)
-//                }
-//                return@runOnUiThread
-//            }
-//
-//            val disconnectFloatView =
-//                floatViewFactory.createFloatView<NetworkReconnectFloatView>(NetworkReconnectFloatData(MODE_APPLICATION)) ?: return@runOnUiThread
-//            disconnectFloatView.updateWithConnectType(bizDisconnected, imDisconnected)
-//            disconnectFloatView.setOnClickListener {
-//                removeDisconnectFloatView()
-//                tryReConnect()
-//            }
-//            Log.i(
-//                TAG_DISCONNECT_TIP,
-//                "addDisconnectFloatView, bizDisconnected:${bizDisconnected}, imDisconnected:${imDisconnected}"
-//            )
-//            WindowManagerProxy.getWindowManager().addView(disconnectFloatView)
-//        }
-    }
-
-    private fun tryReConnect() {
-        connectType2ConnectStatus[ConnectType.BIZ]?.takeIf { it.isDisconnected() }?.let {
-            Log.i(TAG_DISCONNECT_TIP, "tryReConnect biz")
-            connectType2ClickListener[ConnectType.BIZ]?.invoke()
-        }
-
-        connectType2ConnectStatus[ConnectType.IM]?.takeIf { it.isDisconnected() }?.let {
-            Log.i(TAG_DISCONNECT_TIP, "tryReConnect im")
-            connectType2ClickListener[ConnectType.IM]?.invoke()
-        }
-    }
-
-    fun removeDisconnectFloatView() {
-        runOnUiThread {
-            Log.i(
-                TAG_DISCONNECT_TIP,
-                "removeDisconnectFloatView, disconnectFloatView is add:${
-                    WindowManagerProxy.getWindowManager().isFloatViewAdded(FloatWindowType.NETWORK_DISCONNECT_TIP)
-                }"
-            )
-            WindowManagerProxy.getWindowManager().removeFloatViewByType(FloatWindowType.NETWORK_DISCONNECT_TIP, "network resume")
-        }
-    }
-
-    private const val TAG_DISCONNECT_TIP = "tag_disconnect_tip"
-}
-
-interface ConnectStatusListener {
-    fun onConnectStatusChanged(type: ConnectType, status: ConnectStatus)
-}

+ 38 - 116
app/src/main/java/com/adealink/weparty/network/NetworkManager.kt

@@ -1,11 +1,9 @@
 package com.adealink.weparty.network
 
 import android.app.Application
+import com.adealink.frame.base.Rlt
 import com.adealink.frame.coroutine.dispatcher.Dispatcher
 import com.adealink.frame.log.Log
-import com.adealink.frame.network.IConnectStateListener
-import com.adealink.frame.network.ISocket
-import com.adealink.frame.network.stat.NetQualityStatEvent
 import com.adealink.frame.network.util.removeNetworkCallbacks
 import com.adealink.frame.network.util.runNetworkThread
 import com.adealink.frame.util.ActivityLifecycleCallbacksExt
@@ -17,29 +15,27 @@ import com.adealink.weparty.App
 import com.adealink.weparty.module.account.AccountModule
 import com.adealink.weparty.module.account.ILoginListener
 import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
 import kotlinx.coroutines.SupervisorJob
-import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
 
 /**
  * 网络管理器
  */
-class NetworkManager : INetworkManager, ILoginListener, IConnectStateListener,
-    OnNetworkListener, ActivityLifecycleCallbacksExt,
+class NetworkManager : INetworkManager,
+    ILoginListener,
+    OnNetworkListener,
+    ActivityLifecycleCallbacksExt,
     CoroutineScope by CoroutineScope(SupervisorJob() + Dispatcher.WENEXT_THREAD_POOL) {
 
     companion object {
         private const val TAG_NETWORK = "tag_network"
         private const val TAG_PING = "tag_ping"
-        private const val PING_DEFAULT_INTERVAL = 10 * 1000L
-        private const val RTC_LEAVE_CHANNEL_DELAY = 20_000L
+        private const val PING_DEFAULT_INTERVAL = 5 * 1000L
     }
 
-    // TODO: ping接口修改为socket接口
-//    private val pingSocketService by lazy {
-//        App.instance.networkService.getSocketService(PingSocketService::class.java)
-//    }
+    private val pingHttpService by lazy {
+        App.instance.networkService.getHttpService(PingHttpService::class.java)
+    }
 
     private var pingInterval = PING_DEFAULT_INTERVAL
     private val pingRunnable by lazy {
@@ -48,28 +44,19 @@ class NetworkManager : INetworkManager, ILoginListener, IConnectStateListener,
             startPing(pingInterval)
         }
     }
-    private var netQualityStatEvent: NetQualityStatEvent? = null
-
-    private var rtcLeaveChannelJob: Job? = null
 
     override fun init(application: Application) {
         AccountModule.registerListener(this)
         if (AccountModule.isLogin()) {
             handleLogin()
         }
-        ConnectionStatusManager.addReconnectClickListener(
-            ConnectType.BIZ,
-            this::socketConnect
-        )
     }
 
     private fun handleLogin() {
         Log.d(TAG_NETWORK, "handleLogin")
-        netQualityStatEvent = NetQualityStatEvent(NetQualityStatEvent.Action.RTT)
-        App.instance.networkService.registerConnectStateListener(this)
-        socketConnect()
         AppUtil.registerActivityLifecycleCallbacks(this)
         registerNetworkListener(this)
+        startPing()
     }
 
     override fun onLogin() {
@@ -80,90 +67,30 @@ class NetworkManager : INetworkManager, ILoginListener, IConnectStateListener,
     override fun onLogout() {
         super.onLogout()
         Log.d(TAG_NETWORK, "onLogout")
-        netQualityStatEvent?.send()
-        netQualityStatEvent = null
-        App.instance.networkService.disConnect(ISocket.CloseCode.NORMAL)
-        App.instance.networkService.unregisterConnectStateListener(this)
         AppUtil.unregisterActivityLifecycleCallbacks(this)
         unregisterNetworkListener(this)
-        ConnectionStatusManager.removeDisconnectFloatView()
         stopPing()
     }
 
-    override fun onConnectStateChanged(
-        connectState: ISocket.ConnectState,
-        reason: ISocket.ConnectStateReason
-    ) {
-        Log.i(TAG_NETWORK, "onConnectStateChanged, connectState:${connectState.name}")
-        if (connectState == ISocket.ConnectState.DISCONNECT) {
-            ConnectionStatusManager.notifyConnectStatus(ConnectType.BIZ, ConnectStatus.Disconnected)
-            stopPing()
-            if (rtcLeaveChannelJob == null) {
-                rtcLeaveChannelJob = launch {
-                    /*
-                     * 业务socket断开后,延迟一段时间后离开rtc房间
-                     * 防止用户使用另外的设备登录后, 导致后端检查不到幽灵麦的情况
-                     */
-                    delay(RTC_LEAVE_CHANNEL_DELAY)
-                    // TODO: 网络离线
-                    //RoomModule.tryLeaveChannel(LeaveChannelReason.SOCKET_CLOSED)
+    private fun ping() {
+        launch {
+            Log.d(TAG_PING, "ping")
+            AppUtil.background
+            when (val result = pingHttpService.ping()
+                .apply { Log.logRltD(TAG_PING, "ping result", this) }
+            ) {
+                is Rlt.Success -> {
+
                 }
-            }
-        } else {
-            ConnectionStatusManager.notifyConnectStatus(ConnectType.BIZ, ConnectStatus.ConnectingOrConnected)
-            //正在连接或已连接
-            if (connectState == ISocket.ConnectState.CONNECTED) {
-                startPing(0)
-
-                rtcLeaveChannelJob?.cancel()
-                rtcLeaveChannelJob = null
-                // TODO: 网络恢复,重连
-//                launch {
-//                    val rlt = RoomModule.joinChannel(JoinChannelReason.SOCKET_RECONNECTED)
-//                    if (rlt is Rlt.Failed) {
-//                        Log.i(TAG_NETWORK, "joinChannel failed", rlt)
-//                    }
-//                }
-            }
 
-        }
-    }
+                is Rlt.Failed -> {
 
-    private fun ping() {
-        // TODO: 补充ping逻辑
-//        launch {
-//            Log.d(TAG_PING, "ping")
-//            PingStatEvent(PingStatEvent.Action.PING).send()
-//            val startTime = SystemClock.elapsedRealtime()
-//            when (val result = pingSocketService.ping(
-//                PingReq(
-//                    hashMapOf<Int, String>().apply {
-//                        this[0] = if (AppUtil.background) "0" else "1"
-//                        this[1] = App.instance.mediaManager.getJoinedMediaRoomId()?.toString() ?: ""
-//                    },
-//                    App.instance.mediaManager.getSupportRtc()
-//                )
-//            )
-//                .apply { Log.logRltD(TAG_PING, "ping res, ", this) }
-//            ) {
-//                is Rlt.Success -> {
-//                    netQualityStatEvent?.recordRtt(SystemClock.elapsedRealtime() - startTime)
-//                    pingInterval = result.data.data?.interval ?: PING_DEFAULT_INTERVAL
-//                    val inRoomId = result.data.data?.inRoomId ?: 0
-//                    if (inRoomId == 0L && App.instance.mediaManager.getJoinedMediaRoomId() != null) {
-//                        //房间已掉线,客户端发起重新进房
-//                        App.instance.mediaManager.rejoinRoom()
-//                    }
-//                }
-//
-//                is Rlt.Failed -> {
-//                    netQualityStatEvent?.recordFailed()
-//                }
-//            }
-//        }
+                }
+            }
+        }
     }
 
-    private fun startPing(interval: Long) {
+    private fun startPing(interval: Long = pingInterval) {
         Log.d(TAG_PING, "startPing, pingInterval:$interval")
         removeNetworkCallbacks(pingRunnable)
         runNetworkThread(pingRunnable, interval)
@@ -174,30 +101,16 @@ class NetworkManager : INetworkManager, ILoginListener, IConnectStateListener,
         removeNetworkCallbacks(pingRunnable)
     }
 
-    override fun onNetChanged(available: Boolean) {
-        Log.d(TAG_NETWORK, "onNetChanged, available:$available")
-        if (available) {
-            socketConnect()
-        }
-    }
-
     override fun onEnterForeGround() {
         super.onEnterForeGround()
         Log.d(TAG_NETWORK, "onEnterForeGround")
-        socketConnect()
+        startPing()
     }
 
-    private fun socketConnect() {
-//        if (!AccountModule.isLogin()) {
-//            return
-//        }
-//
-//        if (AppUtil.background) {
-//            Log.i(TAG_NETWORK, "socketConnect, background")
-//            return
-//        }
-//
-//        App.instance.networkService.connect()
+    override fun onEnterBackGround() {
+        super.onEnterBackGround()
+        Log.d(TAG_NETWORK, "onEnterBackGround")
+        stopPing()
     }
 
     override fun pingNow() {
@@ -205,4 +118,13 @@ class NetworkManager : INetworkManager, ILoginListener, IConnectStateListener,
         startPing(interval = 0)
     }
 
+    override fun onNetChanged(available: Boolean) {
+        Log.d(TAG_NETWORK, "onNetChanged, available:$available")
+        if (available) {
+            startPing(0)
+        } else {
+            stopPing()
+        }
+    }
+
 }

+ 4 - 7
app/src/main/java/com/adealink/weparty/network/PingSocketService.kt

@@ -2,15 +2,12 @@ package com.adealink.weparty.network
 
 import com.adealink.frame.base.Rlt
 import com.adealink.frame.network.data.Res
-import com.adealink.frame.network.socket.annotation.Uri
 import com.google.gson.annotations.SerializedName
-import retrofit2.http.Body
+import retrofit2.http.POST
 
-// TODO: 修改为http接口
-interface PingSocketService {
-
-    @Uri("PING")
-    suspend fun ping(@Body req: PingReq): Rlt<Res<PingRes>>
+interface PingHttpService {
+    @POST("user/online/heartbeat")
+    suspend fun ping(): Rlt<Res<Any>>
 
 }