183 lines
5.4 KiB
Python
183 lines
5.4 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
WebSocket连接诊断工具
|
|
快速定位502错误的原因
|
|
"""
|
|
|
|
import asyncio
|
|
import websockets
|
|
import requests
|
|
import socket
|
|
from urllib.parse import urlparse
|
|
import ssl
|
|
import sys
|
|
from config import BACKEND_HOST, BACKEND_WS_URL, get_gui_ws_url, get_saved_token
|
|
|
|
def test_basic_connectivity():
|
|
"""测试基础网络连通性"""
|
|
print("=== 1. 基础连通性测试 ===")
|
|
|
|
# DNS解析测试
|
|
try:
|
|
ip = socket.gethostbyname(BACKEND_HOST)
|
|
print(f"✅ DNS解析成功: {BACKEND_HOST} -> {ip}")
|
|
except Exception as e:
|
|
print(f"❌ DNS解析失败: {e}")
|
|
return False
|
|
|
|
# HTTP连通性测试
|
|
try:
|
|
response = requests.get(f"https://{BACKEND_HOST}", timeout=10)
|
|
print(f"✅ HTTPS连接成功: 状态码 {response.status_code}")
|
|
except requests.exceptions.SSLError as e:
|
|
print(f"⚠️ SSL证书问题: {e}")
|
|
return False
|
|
except requests.exceptions.ConnectionError as e:
|
|
print(f"❌ 连接失败: {e}")
|
|
return False
|
|
except requests.exceptions.Timeout:
|
|
print(f"❌ 连接超时")
|
|
return False
|
|
except Exception as e:
|
|
print(f"⚠️ HTTPS测试异常: {e}")
|
|
|
|
return True
|
|
|
|
def test_websocket_endpoint():
|
|
"""测试WebSocket端点"""
|
|
print("\n=== 2. WebSocket端点测试 ===")
|
|
|
|
# 获取token
|
|
token = get_saved_token()
|
|
if not token:
|
|
print("❌ 未找到有效token")
|
|
return False
|
|
|
|
print(f"📝 使用token: {token[:20]}...")
|
|
|
|
# 构建WebSocket URL
|
|
ws_url = get_gui_ws_url(token)
|
|
print(f"🔗 WebSocket URL: {ws_url}")
|
|
|
|
return ws_url
|
|
|
|
async def test_websocket_connection(ws_url):
|
|
"""异步测试WebSocket连接"""
|
|
print("\n=== 3. WebSocket连接测试 ===")
|
|
|
|
try:
|
|
print("🔄 尝试连接WebSocket...")
|
|
|
|
# 添加连接超时
|
|
websocket = await asyncio.wait_for(
|
|
websockets.connect(ws_url),
|
|
timeout=15.0
|
|
)
|
|
|
|
print("✅ WebSocket连接成功!")
|
|
|
|
# 测试发送消息
|
|
test_message = {"type": "ping", "data": "connection_test"}
|
|
await websocket.send(str(test_message))
|
|
print("✅ 消息发送成功")
|
|
|
|
# 等待响应
|
|
try:
|
|
response = await asyncio.wait_for(websocket.recv(), timeout=5.0)
|
|
print(f"✅ 收到响应: {response}")
|
|
except asyncio.TimeoutError:
|
|
print("⚠️ 未收到响应(超时5秒)")
|
|
|
|
await websocket.close()
|
|
print("✅ 连接正常关闭")
|
|
return True
|
|
|
|
except websockets.exceptions.InvalidStatusCode as e:
|
|
if e.status_code == 502:
|
|
print("❌ HTTP 502 Bad Gateway - 后端服务器问题")
|
|
print("💡 可能原因:")
|
|
print(" - 后端服务未启动")
|
|
print(" - Nginx配置错误")
|
|
print(" - 服务器资源不足")
|
|
else:
|
|
print(f"❌ HTTP状态码错误: {e.status_code}")
|
|
return False
|
|
|
|
except websockets.exceptions.ConnectionClosedError as e:
|
|
print(f"❌ 连接被关闭: {e}")
|
|
return False
|
|
|
|
except websockets.exceptions.WebSocketException as e:
|
|
print(f"❌ WebSocket异常: {e}")
|
|
return False
|
|
|
|
except asyncio.TimeoutError:
|
|
print("❌ 连接超时 - 服务器可能未响应")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ 未知错误: {type(e).__name__}: {e}")
|
|
return False
|
|
|
|
def test_alternative_endpoints():
|
|
"""测试备用连接方式"""
|
|
print("\n=== 4. 备用端点测试 ===")
|
|
|
|
# 测试HTTP API端点
|
|
try:
|
|
api_url = f"https://{BACKEND_HOST}/api/health"
|
|
response = requests.get(api_url, timeout=10)
|
|
print(f"✅ API端点响应: {response.status_code}")
|
|
except Exception as e:
|
|
print(f"⚠️ API端点不可用: {e}")
|
|
|
|
# 测试WebSocket根路径
|
|
try:
|
|
root_ws_url = f"wss://{BACKEND_HOST}/ws/"
|
|
print(f"🔗 测试根WebSocket路径: {root_ws_url}")
|
|
except Exception as e:
|
|
print(f"⚠️ 根路径测试失败: {e}")
|
|
|
|
async def main():
|
|
"""主诊断流程"""
|
|
print("🔍 WebSocket连接诊断工具")
|
|
print("=" * 50)
|
|
|
|
# 1. 基础连通性
|
|
if not test_basic_connectivity():
|
|
print("\n❌ 基础连通性测试失败,请检查网络连接")
|
|
return
|
|
|
|
# 2. WebSocket端点配置
|
|
ws_url = test_websocket_endpoint()
|
|
if not ws_url:
|
|
print("\n❌ WebSocket端点配置错误")
|
|
return
|
|
|
|
# 3. WebSocket连接测试
|
|
success = await test_websocket_connection(ws_url)
|
|
|
|
# 4. 备用测试
|
|
test_alternative_endpoints()
|
|
|
|
# 5. 总结和建议
|
|
print("\n" + "=" * 50)
|
|
if success:
|
|
print("🎉 诊断完成: WebSocket连接正常!")
|
|
else:
|
|
print("❌ 诊断完成: 发现连接问题")
|
|
print("\n🔧 建议解决方案:")
|
|
print("1. 联系服务器管理员检查后端服务状态")
|
|
print("2. 检查Nginx WebSocket配置")
|
|
print("3. 确认防火墙和安全组设置")
|
|
print("4. 检查服务器资源使用情况")
|
|
print("5. 验证SSL证书有效性")
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
asyncio.run(main())
|
|
except KeyboardInterrupt:
|
|
print("\n\n⏹️ 诊断被用户中断")
|
|
except Exception as e:
|
|
print(f"\n\n💥 诊断工具异常: {e}") |