import json
import websocket
import ssl
import threading
import time
import hmac
import hashlib
import base64

# OKX 私有 WebSocket URL
OKX_WS_URL = "wss://ws.okx.com:8443/ws/v5/private"

# API 认证信息
API_KEY = "4a4d18ed-f671-4a26-92cb-c34388407d41"
SECRET_KEY = "A209BB83BEBC32727E3E807E43310554"
PASSPHRASE = "@89687828cC"

# 生成 OKX API 认证签名
def generate_signature(timestamp, method, request_path, body):
    message = f"{timestamp}{method}{request_path}{body}"
    mac = hmac.new(SECRET_KEY.encode(), message.encode(), hashlib.sha256)
    return base64.b64encode(mac.digest()).decode()

# WebSocket 连接成功时的回调函数
def on_open(ws):
    print("WebSocket连接已打开，开始认证...")
    timestamp = str(int(time.time()))
    signature = generate_signature(timestamp, "GET", "/users/self/verify", "")
    auth_message = {
        "op": "login",
        "args": [
            {
                "apiKey": API_KEY,
                "passphrase": PASSPHRASE,
                "timestamp": timestamp,
                "sign": signature
            }
        ]
    }
    ws.send(json.dumps(auth_message))
    
    
    # 启动心跳线程
    threading.Thread(target=send_heartbeat, args=(ws,), daemon=True).start()

# WebSocket 接收到消息时的回调函数
def on_message(ws, message):
    if message == "pong":
        print("收到 pong 消息，连接正常")
        return  # 不需要解析 pong 消息
    
    if not message.strip():  # 避免解析空字符串
        print("⚠️ 收到空消息，忽略")
        return
    try:
        data = json.loads(message)
    except json.JSONDecodeError:
        print(f"⚠️ 无法解析消息: {message}")
        return
    
    print("收到的消息:", message)
    if "event" in data and data["event"] == "login":
        print("认证成功...")


# WebSocket 连接关闭时的回调函数
def on_close(ws, close_status_code, close_msg):
    print("WebSocket连接已关闭，准备重连...")
    reconnect_ws()  # 触发重连

# WebSocket 错误时的回调函数
def on_error(ws, error):
    print(f"WebSocket发生错误: {error}")
    reconnect_ws()  # 触发重连

# 重新连接 WebSocket
def reconnect_ws():
    time.sleep(5)  # 休息5秒，避免频繁请求
    print("正在重新连接 WebSocket...")
    start_ws()  # 重新启动 WebSocket 连接
    
# **心跳线程**
def send_heartbeat(ws):
    
    while True:
        try:
            if ws.sock and ws.sock.connected:  # 确保连接仍然存在
                ws.send("ping")  # 发送 ping 消息
                print("发送心跳 ping")
            time.sleep(20)  # 每 20 秒发送一次心跳
        except Exception as e:
            print(f"心跳错误: {e}")
            break  # 如果 WebSocket 断开，则停止心跳线程

# 创建并启动 WebSocket 连接
def start_ws():
    ws = websocket.WebSocketApp(
        OKX_WS_URL,
        on_open=on_open,
        on_message=on_message,
        on_close=on_close,
        on_error=on_error
    )
    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})

if __name__ == "__main__":
    # 启动 WebSocket 线程
    ws_thread = threading.Thread(target=start_ws, daemon=True)
    ws_thread.start()

    # 主线程保持运行，避免程序退出
    while True:
        time.sleep(1)




