ef4d485a by huangyf2

优化rss,优化连接速度

1 parent c428ab60
Showing 1 changed file with 65 additions and 9 deletions
...@@ -274,15 +274,17 @@ class BLEClient: ...@@ -274,15 +274,17 @@ class BLEClient:
274 274
275 async def _background_connect(self, peripheral_id, request_id): 275 async def _background_connect(self, peripheral_id, request_id):
276 """ 276 """
277 后台执行BLE连接任务 277 后台执行BLE连接任务 - 优化版本
278 策略: 278 策略:
279 1. 验证设备地址格式 279 1. 验证设备地址格式
280 2. 异步断开旧连接(不阻塞新连接) 280 2. 检查连接历史,快速重连已连接过的设备
281 3. 执行新连接(带超时) 281 3. 异步断开旧连接(不阻塞新连接)
282 4. 连接完成后发送状态通知 282 4. 执行新连接(带超时和重试机制)
283 5. 连接完成后发送状态通知并更新历史
283 """ 284 """
284 try: 285 try:
285 self._connecting = True 286 self._connecting = True
287 current_time = time.time()
286 288
287 # 步骤0: 验证设备地址格式 289 # 步骤0: 验证设备地址格式
288 if not peripheral_id or len(peripheral_id) < 12: 290 if not peripheral_id or len(peripheral_id) < 12:
...@@ -304,6 +306,35 @@ class BLEClient: ...@@ -304,6 +306,35 @@ class BLEClient:
304 self._connecting = False 306 self._connecting = False
305 return 307 return
306 308
309 # 优化策略1: 检查是否是最近连接过的设备,如果是且连接历史良好,使用更短的超时
310 connection_optimized = False
311 if peripheral_id in self._connection_history:
312 success_time, last_attempt, success_count = self._connection_history[peripheral_id]
313 # 如果最近30秒内成功连接过,且成功次数>=1,使用优化连接
314 if current_time - success_time < 30.0 and success_count >= 1:
315 connection_optimized = True
316 await log_message("连接", f"检测到快速重连设备: {peripheral_id} (历史成功: {success_count}次)")
317
318 # 优化策略2: 如果当前已连接的是同一设备,直接返回成功
319 if (self.client and self.client.is_connected and
320 self._last_connected_address == peripheral_id):
321 await log_message("连接", f"设备已连接: {peripheral_id}")
322 success_response = json.dumps({
323 "jsonrpc": "2.0",
324 "method": "connectionStatus",
325 "params": {
326 "connected": True,
327 "peripheralId": peripheral_id,
328 "cached": True
329 },
330 "id": request_id
331 })
332 await log_message("下发", success_response)
333 if self.websocket and not self.websocket.closed:
334 await self.websocket.send(success_response)
335 self._connecting = False
336 return
337
307 # 步骤1: 异步断开旧连接(最多等待1秒,超时后强制清理) 338 # 步骤1: 异步断开旧连接(最多等待1秒,超时后强制清理)
308 old_client = self.client 339 old_client = self.client
309 if old_client: 340 if old_client:
...@@ -337,15 +368,18 @@ class BLEClient: ...@@ -337,15 +368,18 @@ class BLEClient:
337 # 注意:BLE连接包含多个阶段: 368 # 注意:BLE连接包含多个阶段:
338 # 1. 建立物理连接(通常1-2秒) 369 # 1. 建立物理连接(通常1-2秒)
339 # 2. 发现服务(get_services)(通常3-8秒,是主要瓶颈) 370 # 2. 发现服务(get_services)(通常3-8秒,是主要瓶颈)
340 # 因此总超时设置为8秒,确保大多数设备能完成连接 371 # 优化:已连接过的设备使用更短的超时(6秒),新设备使用8秒
341 client = None 372 client = None
373 connect_timeout = 6.0 if connection_optimized else 8.0
374
342 try: 375 try:
343 # BleakClient的超时只影响物理连接阶段 376 # BleakClient的超时只影响物理连接阶段
344 client = BleakClient(peripheral_id, timeout=10.0) 377 client = BleakClient(peripheral_id, timeout=10.0)
345 client.set_disconnected_callback(self.on_disconnect) 378 client.set_disconnected_callback(self.on_disconnect)
346 379
347 # 连接操作,总超时8秒(覆盖物理连接+服务发现) 380 # 连接操作,根据连接历史调整超时
348 await asyncio.wait_for(client.connect(), timeout=8.0) 381 await log_message("连接", f"开始连接设备: {peripheral_id} (超时: {connect_timeout}秒)")
382 await asyncio.wait_for(client.connect(), timeout=connect_timeout)
349 383
350 # 验证连接状态 384 # 验证连接状态
351 if not client.is_connected: 385 if not client.is_connected:
...@@ -358,9 +392,17 @@ class BLEClient: ...@@ -358,9 +392,17 @@ class BLEClient:
358 392
359 # 连接成功,保存客户端引用 393 # 连接成功,保存客户端引用
360 self.client = client 394 self.client = client
395 self._last_connected_address = peripheral_id
361 self._connecting = False 396 self._connecting = False
362 client = None # 避免finally中重复清理 397 client = None # 避免finally中重复清理
363 398
399 # 更新连接历史
400 if peripheral_id in self._connection_history:
401 success_time, _, success_count = self._connection_history[peripheral_id]
402 self._connection_history[peripheral_id] = (current_time, current_time, success_count + 1)
403 else:
404 self._connection_history[peripheral_id] = (current_time, current_time, 1)
405
364 await log_message("连接", f"成功连接到设备: {peripheral_id}") 406 await log_message("连接", f"成功连接到设备: {peripheral_id}")
365 407
366 # 发送连接成功通知 408 # 发送连接成功通知
...@@ -379,12 +421,19 @@ class BLEClient: ...@@ -379,12 +421,19 @@ class BLEClient:
379 421
380 except asyncio.TimeoutError: 422 except asyncio.TimeoutError:
381 self._connecting = False 423 self._connecting = False
382 error_msg = "连接BLE设备超时(8秒),可能是服务发现阶段耗时过长" 424 error_msg = f"连接BLE设备超时({connect_timeout}秒),可能是服务发现阶段耗时过长"
383 await log_exception_async( 425 await log_exception_async(
384 asyncio.TimeoutError(error_msg), 426 asyncio.TimeoutError(error_msg),
385 "后台连接-连接超时" 427 "后台连接-连接超时"
386 ) 428 )
387 429
430 # 更新连接历史(记录失败)
431 if peripheral_id in self._connection_history:
432 success_time, _, success_count = self._connection_history[peripheral_id]
433 self._connection_history[peripheral_id] = (success_time, current_time, success_count)
434 else:
435 self._connection_history[peripheral_id] = (0, current_time, 0)
436
388 # 清理超时的client资源 437 # 清理超时的client资源
389 if client is not None: 438 if client is not None:
390 try: 439 try:
...@@ -510,6 +559,8 @@ class BLEClient: ...@@ -510,6 +559,8 @@ class BLEClient:
510 current_time = time.time() 559 current_time = time.time()
511 self._best_rssi_device = None 560 self._best_rssi_device = None
512 self._best_rssi_value = -999 561 self._best_rssi_value = -999
562 found = False
563 scan_error = None
513 564
514 # 清理过期缓存 565 # 清理过期缓存
515 expired_addresses = [ 566 expired_addresses = [
...@@ -544,7 +595,6 @@ class BLEClient: ...@@ -544,7 +595,6 @@ class BLEClient:
544 if not found: 595 if not found:
545 # 双重扫描:快速扫描后若未发现,再进行扩展扫描;发现即停 596 # 双重扫描:快速扫描后若未发现,再进行扩展扫描;发现即停
546 phases = [("active", 3.0), ("passive", 6.0)] 597 phases = [("active", 3.0), ("passive", 6.0)]
547 scan_error = None
548 598
549 for phase_index, (scan_mode, duration) in enumerate(phases, start=1): 599 for phase_index, (scan_mode, duration) in enumerate(phases, start=1):
550 self.target_device = None 600 self.target_device = None
...@@ -592,10 +642,16 @@ class BLEClient: ...@@ -592,10 +642,16 @@ class BLEClient:
592 # 检查是否找到设备 642 # 检查是否找到设备
593 if self.target_device: 643 if self.target_device:
594 found = True 644 found = True
645 # 优先使用信号最强的设备
646 if self._best_rssi_device and self._best_rssi_value > -999:
647 self.target_device = self._best_rssi_device
595 break 648 break
596 else: 649 else:
597 print(f"第{phase_index}阶段未找到设备") 650 print(f"第{phase_index}阶段未找到设备")
598 651
652 # 更新扫描时间
653 self._last_scan_time = time.time()
654
599 # 处理扫描结果 655 # 处理扫描结果
600 if found: 656 if found:
601 device, adv_data = self.target_device 657 device, adv_data = self.target_device
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!