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