0e90a8e9 by huangyf2

增加名字不为空,增加双重扫描

1 parent 8b08c35f
Showing 1 changed file with 92 additions and 28 deletions
...@@ -131,20 +131,43 @@ class BLEClient: ...@@ -131,20 +131,43 @@ class BLEClient:
131 131
132 def on_disconnect(self, client): 132 def on_disconnect(self, client):
133 print("BLE连接断开,关闭WebSocket") 133 print("BLE连接断开,关闭WebSocket")
134 # 设置关闭标志
135 self._shutdown = True
136 # 在事件循环中关闭WebSocket
134 if self.websocket and not self.websocket.closed: 137 if self.websocket and not self.websocket.closed:
135 asyncio.create_task(self.close_websocket()) 138 try:
139 # 尝试获取当前事件循环
140 loop = asyncio.get_event_loop()
141 if loop.is_running():
142 loop.create_task(self.close_websocket())
143 except Exception:
144 # 如果没有事件循环,直接设置为None(延迟清理)
145 pass
136 146
137 async def close_websocket(self): 147 async def close_websocket(self):
148 """主动关闭WebSocket连接"""
138 if self.websocket: 149 if self.websocket:
139 try: 150 try:
140 await self.websocket.close() 151 if not self.websocket.closed:
152 # 使用1000状态码正常关闭
153 await self.websocket.close(code=1000, reason="BLE connection closed")
154 print("WebSocket连接已关闭")
141 except Exception as e: 155 except Exception as e:
142 print(f"关闭WebSocket时出错: {e}") 156 print(f"关闭WebSocket时出错: {e}")
143 finally: 157 finally:
144 self.websocket = None 158 self.websocket = None
159 self._shutdown = True
145 160
146 def detection_callback(self, device, advertisement_data): 161 def detection_callback(self, device, advertisement_data):
147 if any(service_uuid in advertisement_data.service_uuids for service_uuid in self.services): 162 if any(service_uuid in advertisement_data.service_uuids for service_uuid in self.services):
163 # 优先使用广播包中的local_name
164 device_name = advertisement_data.local_name if advertisement_data.local_name else (device.name if device.name else "")
165
166 # 丢弃名字为空的设备
167 if not device_name or device_name.strip() == "":
168 print(f"跳过名字为空的设备: {device.address}")
169 return None
170
148 self.target_device = (device, advertisement_data) 171 self.target_device = (device, advertisement_data)
149 if not self.target_device: 172 if not self.target_device:
150 print("未找到匹配设备") 173 print("未找到匹配设备")
...@@ -152,14 +175,15 @@ class BLEClient: ...@@ -152,14 +175,15 @@ class BLEClient:
152 else: 175 else:
153 device, adv_data = self.target_device 176 device, adv_data = self.target_device
154 print("\n找到目标设备:") 177 print("\n找到目标设备:")
155 print(f"设备名称: {device.name}") 178 print(f"设备名称(从广播包): {device_name}")
156 print(f"设备地址: {device.address}") 179 print(f"设备地址: {device.address}")
157 print(f"信号强度: {device.rssi} dBm") 180 print(f"信号强度: {device.rssi} dBm")
158 print("\n广播信息:") 181 print("\n广播信息:")
159 print(f"服务UUID列表: {adv_data.service_uuids}") 182 print(f"服务UUID列表: {adv_data.service_uuids}")
160 print(f"制造商数据: {adv_data.manufacturer_data}") 183 print(f"制造商数据: {adv_data.manufacturer_data}")
161 print(f"服务数据: {adv_data.service_data}") 184 print(f"服务数据: {adv_data.service_data}")
162 print(f"本地名称: {adv_data.local_name}") 185 print(f"本地名称(local_name): {adv_data.local_name}")
186 print(f"设备名称(device.name): {device.name if device.name else 'N/A'}")
163 # 发现设备后,尝试立即停止扫描 187 # 发现设备后,尝试立即停止扫描
164 try: 188 try:
165 if self._scanner is not None: 189 if self._scanner is not None:
...@@ -178,12 +202,18 @@ class BLEClient: ...@@ -178,12 +202,18 @@ class BLEClient:
178 202
179 async def handle_client(self, websocket, path): 203 async def handle_client(self, websocket, path):
180 self.websocket = websocket 204 self.websocket = websocket
205 self._shutdown = False # 重置关闭标志
181 if path != "/scratch/ble": 206 if path != "/scratch/ble":
182 await websocket.close(code=1003, reason="Path not allowed") 207 await websocket.close(code=1003, reason="Path not allowed")
183 return 208 return
184 209
185 try: 210 try:
186 async for message in websocket: 211 async for message in websocket:
212 # 检查是否应该关闭连接
213 if self._shutdown:
214 print("检测到关闭标志,终止消息接收")
215 break
216
187 try: 217 try:
188 await log_message("接收", message) 218 await log_message("接收", message)
189 request = json.loads(message) 219 request = json.loads(message)
...@@ -230,24 +260,28 @@ class BLEClient: ...@@ -230,24 +260,28 @@ class BLEClient:
230 260
231 if found: 261 if found:
232 device, adv_data = self.target_device 262 device, adv_data = self.target_device
263 # 优先使用广播包中的local_name,如果没有则使用device.name
264 device_name = adv_data.local_name if adv_data.local_name else (device.name if device.name else "")
233 discover_response = json.dumps({ 265 discover_response = json.dumps({
234 "jsonrpc": "2.0", 266 "jsonrpc": "2.0",
235 "method": "didDiscoverPeripheral", 267 "method": "didDiscoverPeripheral",
236 "params": { 268 "params": {
237 "name": device.name, 269 "name": device_name,
238 "peripheralId": device.address, 270 "peripheralId": device.address,
239 "rssi": device.rssi 271 "rssi": device.rssi
240 } 272 }
241 }) 273 })
242 await log_message("下发", discover_response) 274 await log_message("下发", discover_response)
275 if not websocket.closed:
243 await websocket.send(discover_response) 276 await websocket.send(discover_response)
244 277
245 result_response = json.dumps({ 278 result_response = json.dumps({
246 "jsonrpc": "2.0", 279 "jsonrpc": "2.0",
247 "result": None, 280 "result": None,
248 "id": request_id 281 "id": request_id if request_id else 0
249 }) 282 })
250 await log_message("下发", result_response) 283 await log_message("下发", result_response)
284 if not websocket.closed:
251 await websocket.send(result_response) 285 await websocket.send(result_response)
252 286
253 elif method == "connect": 287 elif method == "connect":
...@@ -272,22 +306,25 @@ class BLEClient: ...@@ -272,22 +306,25 @@ class BLEClient:
272 "id": request_id 306 "id": request_id
273 }) 307 })
274 await log_message("下发", response) 308 await log_message("下发", response)
309 if not websocket.closed:
275 await websocket.send(response) 310 await websocket.send(response)
276 else: 311 else:
277 error_response = json.dumps({ 312 error_response = json.dumps({
278 "jsonrpc": "2.0", 313 "jsonrpc": "2.0",
279 "error": {"code": -1, "message": "连接失败"}, 314 "result": None,
280 "id": request_id 315 "id": request_id if request_id else 0
281 }) 316 })
282 await log_message("下发", error_response) 317 await log_message("下发", error_response)
318 if not websocket.closed:
283 await websocket.send(error_response) 319 await websocket.send(error_response)
284 except Exception as e: 320 except Exception as e:
285 error_response = json.dumps({ 321 error_response = json.dumps({
286 "jsonrpc": "2.0", 322 "jsonrpc": "2.0",
287 "error": {"code": -1, "message": f"连接异常: {str(e)}"}, 323 "result": None,
288 "id": request_id 324 "id": request_id if request_id else 0
289 }) 325 })
290 await log_message("下发", error_response) 326 await log_message("下发", error_response)
327 if not websocket.closed:
291 await websocket.send(error_response) 328 await websocket.send(error_response)
292 if self.client: 329 if self.client:
293 self.client = None 330 self.client = None
...@@ -314,22 +351,25 @@ class BLEClient: ...@@ -314,22 +351,25 @@ class BLEClient:
314 "id": request_id 351 "id": request_id
315 }) 352 })
316 await log_message("下发", response) 353 await log_message("下发", response)
354 if not websocket.closed:
317 await websocket.send(response) 355 await websocket.send(response)
318 except Exception as e: 356 except Exception as e:
319 error_response = json.dumps({ 357 error_response = json.dumps({
320 "jsonrpc": "2.0", 358 "jsonrpc": "2.0",
321 "error": {"code": -1, "message": f"写入失败: {str(e)}"}, 359 "result": None,
322 "id": request_id 360 "id": request_id if request_id else 0
323 }) 361 })
324 await log_message("下发", error_response) 362 await log_message("下发", error_response)
363 if not websocket.closed:
325 await websocket.send(error_response) 364 await websocket.send(error_response)
326 else: 365 else:
327 error_response = json.dumps({ 366 error_response = json.dumps({
328 "jsonrpc": "2.0", 367 "jsonrpc": "2.0",
329 "error": {"code": -1, "message": "未连接或参数不全"}, 368 "result": None,
330 "id": request_id 369 "id": request_id if request_id else 0
331 }) 370 })
332 await log_message("下发", error_response) 371 await log_message("下发", error_response)
372 if not websocket.closed:
333 await websocket.send(error_response) 373 await websocket.send(error_response)
334 374
335 elif method == "read": 375 elif method == "read":
...@@ -338,7 +378,11 @@ class BLEClient: ...@@ -338,7 +378,11 @@ class BLEClient:
338 378
339 if all([service_id, characteristic_id]) and self.client and self.client.is_connected: 379 if all([service_id, characteristic_id]) and self.client and self.client.is_connected:
340 try: 380 try:
341 data = await self.client.read_gatt_char(characteristic_id) 381 # 添加读取超时,避免长时间阻塞
382 data = await asyncio.wait_for(
383 self.client.read_gatt_char(characteristic_id),
384 timeout=10.0
385 )
342 print('read-data',data) 386 print('read-data',data)
343 response = json.dumps({ 387 response = json.dumps({
344 "jsonrpc": "2.0", 388 "jsonrpc": "2.0",
...@@ -350,22 +394,36 @@ class BLEClient: ...@@ -350,22 +394,36 @@ class BLEClient:
350 "id": request_id 394 "id": request_id
351 }) 395 })
352 await log_message("下发", response) 396 await log_message("下发", response)
397 # 检查WebSocket状态后再发送
398 if not websocket.closed:
353 await websocket.send(response) 399 await websocket.send(response)
400 except asyncio.TimeoutError:
401 error_response = json.dumps({
402 "jsonrpc": "2.0",
403 "result": None,
404 "id": request_id if request_id else 0
405 })
406 await log_message("下发", error_response)
407 if not websocket.closed:
408 await websocket.send(error_response)
354 except Exception as e: 409 except Exception as e:
355 error_response = json.dumps({ 410 error_response = json.dumps({
356 "jsonrpc": "2.0", 411 "jsonrpc": "2.0",
357 "error": {"code": -1, "message": f"读取失败: {str(e)}"}, 412 "result": None,
358 "id": request_id 413 "id": request_id if request_id else 0
359 }) 414 })
360 await log_message("下发", error_response) 415 await log_message("下发", error_response)
416 # 检查WebSocket状态后再发送
417 if not websocket.closed:
361 await websocket.send(error_response) 418 await websocket.send(error_response)
362 else: 419 else:
363 error_response = json.dumps({ 420 error_response = json.dumps({
364 "jsonrpc": "2.0", 421 "jsonrpc": "2.0",
365 "error": {"code": -1, "message": "未连接或参数不全"}, 422 "result": None,
366 "id": request_id 423 "id": request_id if request_id else 0
367 }) 424 })
368 await log_message("下发", error_response) 425 await log_message("下发", error_response)
426 if not websocket.closed:
369 await websocket.send(error_response) 427 await websocket.send(error_response)
370 428
371 elif method == "startNotifications": 429 elif method == "startNotifications":
...@@ -392,22 +450,25 @@ class BLEClient: ...@@ -392,22 +450,25 @@ class BLEClient:
392 "id": request_id 450 "id": request_id
393 }) 451 })
394 await log_message("下发", response) 452 await log_message("下发", response)
453 if not websocket.closed:
395 await websocket.send(response) 454 await websocket.send(response)
396 except Exception as e: 455 except Exception as e:
397 error_response = json.dumps({ 456 error_response = json.dumps({
398 "jsonrpc": "2.0", 457 "jsonrpc": "2.0",
399 "error": {"code": -1, "message": f"启动通知失败: {str(e)}"}, 458 "result": None,
400 "id": request_id 459 "id": request_id if request_id else 0
401 }) 460 })
402 await log_message("下发", error_response) 461 await log_message("下发", error_response)
462 if not websocket.closed:
403 await websocket.send(error_response) 463 await websocket.send(error_response)
404 else: 464 else:
405 error_response = json.dumps({ 465 error_response = json.dumps({
406 "jsonrpc": "2.0", 466 "jsonrpc": "2.0",
407 "error": {"code": -1, "message": "未连接或参数不全"}, 467 "result": None,
408 "id": request_id 468 "id": request_id if request_id else 0
409 }) 469 })
410 await log_message("下发", error_response) 470 await log_message("下发", error_response)
471 if not websocket.closed:
411 await websocket.send(error_response) 472 await websocket.send(error_response)
412 473
413 elif method == "ping": 474 elif method == "ping":
...@@ -415,19 +476,21 @@ class BLEClient: ...@@ -415,19 +476,21 @@ class BLEClient:
415 response = json.dumps({ 476 response = json.dumps({
416 "jsonrpc": "2.0", 477 "jsonrpc": "2.0",
417 "result": {"pong": True, "timestamp": int(time.time())}, 478 "result": {"pong": True, "timestamp": int(time.time())},
418 "id": request_id 479 "id": request_id if request_id else 0
419 }) 480 })
420 await log_message("下发", response) 481 await log_message("下发", response)
482 if not websocket.closed:
421 await websocket.send(response) 483 await websocket.send(response)
422 484
423 except json.JSONDecodeError as e: 485 except json.JSONDecodeError as e:
424 error_msg = json.dumps({ 486 error_msg = json.dumps({
425 "jsonrpc": "2.0", 487 "jsonrpc": "2.0",
426 "error": {"code": -32700, "message": "Parse error", "data": str(e)}, 488 "result": None,
427 "id": request.get("id") if request else None 489 "id": request.get("id") if request else 0
428 }) 490 })
429 await log_message("下发", error_msg) 491 await log_message("下发", error_msg)
430 try: 492 try:
493 if not websocket.closed:
431 await websocket.send(error_msg) 494 await websocket.send(error_msg)
432 except Exception: 495 except Exception:
433 pass 496 pass
...@@ -438,11 +501,12 @@ class BLEClient: ...@@ -438,11 +501,12 @@ class BLEClient:
438 501
439 error_msg = json.dumps({ 502 error_msg = json.dumps({
440 "jsonrpc": "2.0", 503 "jsonrpc": "2.0",
441 "error": {"code": -32603, "message": "Internal error", "data": str(e)}, 504 "result": None,
442 "id": request.get("id") if request else None 505 "id": request.get("id") if request else 0
443 }) 506 })
444 await log_message("下发", error_msg) 507 await log_message("下发", error_msg)
445 try: 508 try:
509 if not websocket.closed:
446 await websocket.send(error_msg) 510 await websocket.send(error_msg)
447 except Exception: 511 except Exception:
448 pass 512 pass
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!