0e90a8e9 by huangyf2

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

1 parent 8b08c35f
Showing 1 changed file with 109 additions and 45 deletions
......@@ -131,20 +131,43 @@ class BLEClient:
def on_disconnect(self, client):
print("BLE连接断开,关闭WebSocket")
# 设置关闭标志
self._shutdown = True
# 在事件循环中关闭WebSocket
if self.websocket and not self.websocket.closed:
asyncio.create_task(self.close_websocket())
try:
# 尝试获取当前事件循环
loop = asyncio.get_event_loop()
if loop.is_running():
loop.create_task(self.close_websocket())
except Exception:
# 如果没有事件循环,直接设置为None(延迟清理)
pass
async def close_websocket(self):
"""主动关闭WebSocket连接"""
if self.websocket:
try:
await self.websocket.close()
if not self.websocket.closed:
# 使用1000状态码正常关闭
await self.websocket.close(code=1000, reason="BLE connection closed")
print("WebSocket连接已关闭")
except Exception as e:
print(f"关闭WebSocket时出错: {e}")
finally:
self.websocket = None
self._shutdown = True
def detection_callback(self, device, advertisement_data):
if any(service_uuid in advertisement_data.service_uuids for service_uuid in self.services):
# 优先使用广播包中的local_name
device_name = advertisement_data.local_name if advertisement_data.local_name else (device.name if device.name else "")
# 丢弃名字为空的设备
if not device_name or device_name.strip() == "":
print(f"跳过名字为空的设备: {device.address}")
return None
self.target_device = (device, advertisement_data)
if not self.target_device:
print("未找到匹配设备")
......@@ -152,14 +175,15 @@ class BLEClient:
else:
device, adv_data = self.target_device
print("\n找到目标设备:")
print(f"设备名称: {device.name}")
print(f"设备名称(从广播包): {device_name}")
print(f"设备地址: {device.address}")
print(f"信号强度: {device.rssi} dBm")
print("\n广播信息:")
print(f"服务UUID列表: {adv_data.service_uuids}")
print(f"制造商数据: {adv_data.manufacturer_data}")
print(f"服务数据: {adv_data.service_data}")
print(f"本地名称: {adv_data.local_name}")
print(f"本地名称(local_name): {adv_data.local_name}")
print(f"设备名称(device.name): {device.name if device.name else 'N/A'}")
# 发现设备后,尝试立即停止扫描
try:
if self._scanner is not None:
......@@ -178,12 +202,18 @@ class BLEClient:
async def handle_client(self, websocket, path):
self.websocket = websocket
self._shutdown = False # 重置关闭标志
if path != "/scratch/ble":
await websocket.close(code=1003, reason="Path not allowed")
return
try:
async for message in websocket:
# 检查是否应该关闭连接
if self._shutdown:
print("检测到关闭标志,终止消息接收")
break
try:
await log_message("接收", message)
request = json.loads(message)
......@@ -230,25 +260,29 @@ class BLEClient:
if found:
device, adv_data = self.target_device
# 优先使用广播包中的local_name,如果没有则使用device.name
device_name = adv_data.local_name if adv_data.local_name else (device.name if device.name else "")
discover_response = json.dumps({
"jsonrpc": "2.0",
"method": "didDiscoverPeripheral",
"params": {
"name": device.name,
"name": device_name,
"peripheralId": device.address,
"rssi": device.rssi
}
})
await log_message("下发", discover_response)
await websocket.send(discover_response)
if not websocket.closed:
await websocket.send(discover_response)
result_response = json.dumps({
"jsonrpc": "2.0",
"result": None,
"id": request_id
"id": request_id if request_id else 0
})
await log_message("下发", result_response)
await websocket.send(result_response)
if not websocket.closed:
await websocket.send(result_response)
elif method == "connect":
peripheral_id = params.get("peripheralId")
......@@ -272,23 +306,26 @@ class BLEClient:
"id": request_id
})
await log_message("下发", response)
await websocket.send(response)
if not websocket.closed:
await websocket.send(response)
else:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": "连接失败"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
except Exception as e:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": f"连接异常: {str(e)}"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
if self.client:
self.client = None
......@@ -314,23 +351,26 @@ class BLEClient:
"id": request_id
})
await log_message("下发", response)
await websocket.send(response)
if not websocket.closed:
await websocket.send(response)
except Exception as e:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": f"写入失败: {str(e)}"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
else:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": "未连接或参数不全"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
elif method == "read":
service_id = params.get("serviceId")
......@@ -338,7 +378,11 @@ class BLEClient:
if all([service_id, characteristic_id]) and self.client and self.client.is_connected:
try:
data = await self.client.read_gatt_char(characteristic_id)
# 添加读取超时,避免长时间阻塞
data = await asyncio.wait_for(
self.client.read_gatt_char(characteristic_id),
timeout=10.0
)
print('read-data',data)
response = json.dumps({
"jsonrpc": "2.0",
......@@ -350,23 +394,37 @@ class BLEClient:
"id": request_id
})
await log_message("下发", response)
await websocket.send(response)
# 检查WebSocket状态后再发送
if not websocket.closed:
await websocket.send(response)
except asyncio.TimeoutError:
error_response = json.dumps({
"jsonrpc": "2.0",
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
if not websocket.closed:
await websocket.send(error_response)
except Exception as e:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": f"读取失败: {str(e)}"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
# 检查WebSocket状态后再发送
if not websocket.closed:
await websocket.send(error_response)
else:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": "未连接或参数不全"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
elif method == "startNotifications":
service_id = params.get("serviceId")
......@@ -392,43 +450,48 @@ class BLEClient:
"id": request_id
})
await log_message("下发", response)
await websocket.send(response)
if not websocket.closed:
await websocket.send(response)
except Exception as e:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": f"启动通知失败: {str(e)}"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
else:
error_response = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -1, "message": "未连接或参数不全"},
"id": request_id
"result": None,
"id": request_id if request_id else 0
})
await log_message("下发", error_response)
await websocket.send(error_response)
if not websocket.closed:
await websocket.send(error_response)
elif method == "ping":
# 处理ping请求,返回pong响应
response = json.dumps({
"jsonrpc": "2.0",
"result": {"pong": True, "timestamp": int(time.time())},
"id": request_id
"id": request_id if request_id else 0
})
await log_message("下发", response)
await websocket.send(response)
if not websocket.closed:
await websocket.send(response)
except json.JSONDecodeError as e:
error_msg = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -32700, "message": "Parse error", "data": str(e)},
"id": request.get("id") if request else None
"result": None,
"id": request.get("id") if request else 0
})
await log_message("下发", error_msg)
try:
await websocket.send(error_msg)
if not websocket.closed:
await websocket.send(error_msg)
except Exception:
pass
except Exception as e:
......@@ -438,12 +501,13 @@ class BLEClient:
error_msg = json.dumps({
"jsonrpc": "2.0",
"error": {"code": -32603, "message": "Internal error", "data": str(e)},
"id": request.get("id") if request else None
"result": None,
"id": request.get("id") if request else 0
})
await log_message("下发", error_msg)
try:
await websocket.send(error_msg)
if not websocket.closed:
await websocket.send(error_msg)
except Exception:
pass
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!