fix(scale): 修复子设备断线后重连慢及连接状态竞态问题
- onDeviceDisconnected 时同步清除 UDP 缓存,使子设备 5s 内即可重连,不再等待指数退避 - ScaleWebSocketServer 用 connectionCount 计数器替代 connections.isNullOrEmpty(),消除 onClose 竞态导致子设备 UI 状态不更新的问题
This commit is contained in:
@@ -156,7 +156,11 @@ object ScaleServiceManager {
|
|||||||
val client = ScaleWebSocketClient().also {
|
val client = ScaleWebSocketClient().also {
|
||||||
it.onScaleData = { data -> aggregator?.onRemoteScaleData(data) }
|
it.onScaleData = { data -> aggregator?.onRemoteScaleData(data) }
|
||||||
it.onScaleEvent = { event -> _onScaleEvent?.invoke(event) }
|
it.onScaleEvent = { event -> _onScaleEvent?.invoke(event) }
|
||||||
it.onDeviceDisconnected = { remoteId -> aggregator?.removeDevice(remoteId) }
|
it.onDeviceDisconnected = { remoteId ->
|
||||||
|
aggregator?.removeDevice(remoteId)
|
||||||
|
// 清除 UDP 缓存,确保子设备下次广播时能重新触发 onDeviceFound,立即重连而非等待指数退避
|
||||||
|
udpReceiver?.removeDevice(remoteId)
|
||||||
|
}
|
||||||
it.onDeviceConnected = { remoteId ->
|
it.onDeviceConnected = { remoteId ->
|
||||||
// 子设备连接成功时,从 Room 读取全量配置并单独推送给该设备
|
// 子设备连接成功时,从 Room 读取全量配置并单独推送给该设备
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
|||||||
@@ -117,7 +117,11 @@ class ScaleWebSocketServer(private val deviceId: String, private val context: Co
|
|||||||
private inner class InternalServer(port: Int) :
|
private inner class InternalServer(port: Int) :
|
||||||
WebSocketServer(InetSocketAddress(port)) {
|
WebSocketServer(InetSocketAddress(port)) {
|
||||||
|
|
||||||
|
/** 当前活跃连接计数,用于替代 connections.isNullOrEmpty() 避免竞态 */
|
||||||
|
private var connectionCount = 0
|
||||||
|
|
||||||
override fun onOpen(conn: WebSocket, handshake: ClientHandshake) {
|
override fun onOpen(conn: WebSocket, handshake: ClientHandshake) {
|
||||||
|
connectionCount++
|
||||||
Log.d(TAG, "主设备已连接: ${conn.remoteSocketAddress}")
|
Log.d(TAG, "主设备已连接: ${conn.remoteSocketAddress}")
|
||||||
onConnectionChanged?.invoke(true)
|
onConnectionChanged?.invoke(true)
|
||||||
// 新客户端连接后,立即推送所有秤的最新数据
|
// 新客户端连接后,立即推送所有秤的最新数据
|
||||||
@@ -132,8 +136,9 @@ class ScaleWebSocketServer(private val deviceId: String, private val context: Co
|
|||||||
|
|
||||||
override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) {
|
override fun onClose(conn: WebSocket, code: Int, reason: String, remote: Boolean) {
|
||||||
Log.d(TAG, "主设备已断开: ${conn.remoteSocketAddress}, reason=$reason")
|
Log.d(TAG, "主设备已断开: ${conn.remoteSocketAddress}, reason=$reason")
|
||||||
// 若已无任何连接,通知子设备 UI 更新为未连接状态
|
// 用计数器判断是否还有活跃连接,避免依赖 connections 集合的移除时机导致竞态
|
||||||
if (server?.connections.isNullOrEmpty()) {
|
if (--connectionCount <= 0) {
|
||||||
|
connectionCount = 0
|
||||||
onConnectionChanged?.invoke(false)
|
onConnectionChanged?.invoke(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user