You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin协程中为UDP通信设置30秒超时检测方案咨询

Android UDP通信超时检测实现方案

针对你的需求,我们可以通过跟踪最后消息接收时间+独立协程定时检查的方式实现30秒超时检测,完全不阻塞原有接收逻辑,仅在超时触发时给出提示。以下是修改后的完整代码:

val myCoroutineScope = lifecycleScope
// 记录最后一次收到消息的时间,初始值设为当前时间
private var lastReceivedTime = System.currentTimeMillis()
// 标记是否已经触发过超时提示,避免重复弹出Toast
private var isTimeoutNotified = false
// 超时阈值:30秒
private const val TIMEOUT_THRESHOLD = 30 * 1000L

if (myCoroutineJob == null || myCoroutineJob?.isCompleted == true) {
    // 重置超时标记和接收时间
    lastReceivedTime = System.currentTimeMillis()
    isTimeoutNotified = false

    myCoroutineJob = myCoroutineScope.launch {
        // 初始化UDP客户端
        withContext(Dispatchers.IO) {
            client = Client()
        }

        // 启动超时检测协程:独立循环,不阻塞接收逻辑
        launch {
            while (isActive) {
                val currentTime = System.currentTimeMillis()
                // 判断是否超过超时阈值且未提示过
                if (currentTime - lastReceivedTime > TIMEOUT_THRESHOLD && !isTimeoutNotified) {
                    isTimeoutNotified = true
                    // 日志提示
                    Log.w("UDP_TIMEOUT", "已超过30秒未收到服务器消息,通信可能中断")
                    // Toast提示:需要切换到主线程
                    withContext(Dispatchers.Main) {
                        Toast.makeText(context, "通信已中断,请检查连接", Toast.LENGTH_SHORT).show()
                    }
                }
                // 每隔1秒检查一次,降低资源消耗
                delay(1000)
            }
        }

        // 消息接收监听:收到消息时更新最后接收时间,重置超时标记
        client?.dataReceivedListeners?.add { data ->
            try {
                receivedText = decompress(data)
                val jsonObject = JSONObject(receivedText.toString())

                // 原有消息处理逻辑...

                // 更新最后接收时间,重置超时标记
                lastReceivedTime = System.currentTimeMillis()
                isTimeoutNotified = false

            } catch (e: JSONException) {
                // 原有错误处理逻辑...
            }
        }
    }
}

关键逻辑说明:

  • 时间跟踪:用lastReceivedTime记录每次收到消息的时间,每次接收成功就更新这个值。
  • 独立检测协程:单独启动一个协程做循环检查,每隔1秒判断一次是否超时,避免阻塞接收流程。
  • 重复提示控制:用isTimeoutNotified标记是否已经弹出过提示,避免短时间内重复触发。
  • 生命周期绑定:检测协程在myCoroutineJob的作用域内,随页面生命周期自动销毁,避免内存泄漏。
  • 线程切换:Toast必须在主线程显示,所以用withContext(Dispatchers.Main)切换线程。

内容的提问来源于stack exchange,提问作者Fabio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 10:02:41