m.py 10.5 KB
import asyncio
import json
import websockets

# 预定义的下发通知列表
NOTIFICATIONS = [
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W4ECAgDgXQ=="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W4ECAgDgXQ=="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W4ECAgDgXQ=="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W4ECAgDgXQ=="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W1EDAVwADF0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALQAvAC8ALV0="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "W4ECAgDgXQ=="}},
    {"jsonrpc": "2.0", "method": "characteristicDidChange", "params": {"serviceId": "00b6c4bc-8170-268e-4627-e07f37ed6744", "characteristicId": "01b6c4bc-8170-268e-4627-e07f37ed6744", "message": "WzEJAwkALgAvAC8ALF0="}}
]
async def handle_client(websocket):
    """处理客户端连接"""
    client_ip = websocket.remote_address[0]
    print(f"客户端 {client_ip} 已连接")
    
    try:
        async for message in websocket:
            # 解析接收到的JSON消息
            try:
                data = json.loads(message)
            except json.JSONDecodeError:
                print(f"无效的JSON数据: {message}")
                continue

            print(f"收到请求:\n{json.dumps(data, indent=2)}")

            # 提取请求参数
            method = data.get("method")
            req_id = data.get("id")
            params = data.get("params", {})

            # 请求路由处理
            if method == "discover" and req_id == 0:
                # 处理设备发现请求
                await websocket.send(json.dumps({
                    "jsonrpc": "2.0",
                    "method": "didDiscoverPeripheral",
                    "params": {
                        "name": "12345",
                        "peripheralId": "E68744E9-02D5-42C1-AD3F-6BF6A7D4A5EC",
                        "rssi": -76
                    }
                }))
                await send_response(websocket, None, 0)

            elif method == "connect" and req_id == 1:
                # 处理连接请求
                print(f"正在连接设备: {params.get('peripheralId')}")
                await send_response(websocket, None, 1)

            elif method == "write" and req_id == 2:
                # 处理数据写入请求
                print(f"写入数据到特征: {params.get('characteristicId')}")
                await send_response(websocket, None, 2)

            elif method == "startNotifications" and req_id == 3:
                # 处理通知订阅请求
                print("已启动特征通知")
                await send_response(websocket, None, 3)
                
                # 发送预定义通知流
                for idx, notification in enumerate(NOTIFICATIONS):
                    await websocket.send(json.dumps(notification))
                    print(f"已发送通知 #{idx+1}")
                    await asyncio.sleep(1)  # 每秒发送一个通知

    except websockets.exceptions.ConnectionClosed:
        print(f"客户端 {client_ip} 已断开连接")

async def send_response(websocket, result, req_id):
    """发送标准响应"""
    response = {
        "jsonrpc": "2.0",
        "result": result,
        "id": req_id
    }
    await websocket.send(json.dumps(response))
    print(f"已发送响应 ID {req_id}")

async def main():
    """启动WebSocket服务器"""
    server = await websockets.serve(
        handle_client,
        host="0.0.0.0",
        port=20111,
        ping_interval=None
    )
    
    print(f"WebSocket服务器已启动,监听 ws://0.0.0.0:20111")
    print("按 Ctrl+C 停止服务器")
    
    await server.wait_closed()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\n服务器已关闭")