From af737b910cc5222915d29fa84e61db5668f3e039 Mon Sep 17 00:00:00 2001 From: lvmeng <848755140@qq.com> Date: Wed, 6 May 2026 10:01:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(scale):=20=E4=BF=AE=E5=A4=8D=20UdpBroadcast?= =?UTF-8?q?Sender=20=E5=90=AF=E5=8A=A8=E6=97=B6=20IP=20=E4=B8=BA=E7=A9=BA?= =?UTF-8?q?=E5=AF=BC=E8=87=B4=E5=B9=BF=E6=92=AD=E5=A4=B1=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - UdpBroadcastSender 改为接收 ipProvider 函数替代静态 localIp 参数,每次广播时动态获取 IP - IP 为空时跳过本次广播并等待下一周期重试,避免设备启动时网络未就绪导致广播携带空 IP - ScaleServiceManager 更新调用方式,传入 lambda 动态获取 IP Co-Authored-By: Claude Sonnet 4.6 --- .../shuwei/dish/match/scale/ScaleServiceManager.kt | 5 ++--- .../shuwei/dish/match/scale/UdpBroadcastSender.kt | 14 +++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/shuwei/dish/match/scale/ScaleServiceManager.kt b/app/src/main/java/com/shuwei/dish/match/scale/ScaleServiceManager.kt index ed8cc65..173288b 100644 --- a/app/src/main/java/com/shuwei/dish/match/scale/ScaleServiceManager.kt +++ b/app/src/main/java/com/shuwei/dish/match/scale/ScaleServiceManager.kt @@ -128,9 +128,8 @@ object ScaleServiceManager { if (role == DeviceRole.MASTER) { startMasterServices(context, deviceId) } else { - // 子设备:启动 UDP 广播,作为 mDNS 的兜底发现机制 - val localIp = getLocalIp(context) - udpSender = UdpBroadcastSender(deviceId, localIp).also { it.start() } + // 子设备:启动 UDP 广播,作为 mDNS 的兜底发现机制;每次广播时动态获取 IP,避免启动时网络未就绪导致 IP 为空 + udpSender = UdpBroadcastSender(deviceId = deviceId, ipProvider = { getLocalIp(context) }).also { it.start() } } } diff --git a/app/src/main/java/com/shuwei/dish/match/scale/UdpBroadcastSender.kt b/app/src/main/java/com/shuwei/dish/match/scale/UdpBroadcastSender.kt index 0eab2d6..f59a616 100644 --- a/app/src/main/java/com/shuwei/dish/match/scale/UdpBroadcastSender.kt +++ b/app/src/main/java/com/shuwei/dish/match/scale/UdpBroadcastSender.kt @@ -13,10 +13,12 @@ import java.util.concurrent.TimeUnit * UDP 广播发送器(子设备运行) * 每隔固定间隔向局域网广播本机的 deviceId、IP、WebSocket 端口 * 作为 mDNS 的兜底发现机制,确保主设备能可靠发现子设备 + * + * @param ipProvider 动态获取本机 IP 的函数,每次广播时调用;返回空字符串时跳过本次广播 */ class UdpBroadcastSender( private val deviceId: String, - private val localIp: String, + private val ipProvider: () -> String, private val wsPort: Int = MdnsRegisterManager.WS_PORT ) { @@ -43,12 +45,18 @@ class UdpBroadcastSender( task = scheduler.scheduleWithFixedDelay({ sendBroadcast() }, 0, INTERVAL_SEC, TimeUnit.SECONDS) - Log.d(TAG, "UDP 广播已启动, deviceId=$deviceId, ip=$localIp, port=$wsPort") + Log.d(TAG, "UDP 广播已启动, deviceId=$deviceId, port=$wsPort") } private fun sendBroadcast() { try { - val payload = gson.toJson(Payload(deviceId, localIp, wsPort)) + val ip = ipProvider() + // 网络未就绪时跳过本次广播,等待下一个周期重试 + if (ip.isEmpty()) { + Log.d(TAG, "IP 未就绪,跳过本次广播") + return + } + val payload = gson.toJson(Payload(deviceId, ip, wsPort)) val data = payload.toByteArray(Charsets.UTF_8) DatagramSocket().use { socket -> socket.broadcast = true