add ws
This commit is contained in:
173
dev.py
Normal file
173
dev.py
Normal file
@@ -0,0 +1,173 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
WebSocket 开发服务器启动脚本
|
||||
同时启动 Daphne (WebSocket) 和 Django runserver (开发服务器)
|
||||
支持 Windows 和 Linux
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import platform
|
||||
import signal
|
||||
from pathlib import Path
|
||||
from threading import Thread
|
||||
import time
|
||||
|
||||
|
||||
def main():
|
||||
# 获取项目根目录
|
||||
base_dir = Path(__file__).resolve().parent
|
||||
os.chdir(base_dir)
|
||||
|
||||
print("=" * 70)
|
||||
print("启动 Django 开发服务器 + WebSocket 服务器")
|
||||
print("=" * 70)
|
||||
print()
|
||||
|
||||
# 检测操作系统
|
||||
is_windows = platform.system() == "Windows"
|
||||
|
||||
# 检查虚拟环境(跨平台)
|
||||
if is_windows:
|
||||
# Windows: .venv/Scripts/python.exe
|
||||
venv_python = base_dir / ".venv" / "Scripts" / "python.exe"
|
||||
else:
|
||||
# Linux/Mac: .venv/bin/python
|
||||
venv_python = base_dir / ".venv" / "bin" / "python"
|
||||
|
||||
if venv_python.exists():
|
||||
print("[✓] 使用虚拟环境: .venv")
|
||||
python_exec = str(venv_python)
|
||||
else:
|
||||
print("[!] 未找到 .venv 虚拟环境,使用全局 Python")
|
||||
print("[!] 建议创建虚拟环境: python -m venv .venv")
|
||||
python_exec = sys.executable
|
||||
|
||||
# 检查 daphne 是否安装
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[python_exec, "-m", "daphne", "--version"], capture_output=True, text=True
|
||||
)
|
||||
if result.returncode != 0 and result.returncode != 2:
|
||||
print("[✗] 错误: Daphne 未安装")
|
||||
print("请运行: pip install daphne channels channels-redis")
|
||||
sys.exit(1)
|
||||
except FileNotFoundError:
|
||||
print("[✗] 错误: 无法找到 Python 解释器")
|
||||
sys.exit(1)
|
||||
# 进程列表
|
||||
processes = []
|
||||
|
||||
# 启动两个服务器
|
||||
try:
|
||||
# 启动 Django runserver (端口 8000)
|
||||
print("[*] 启动 Django 开发服务器 (端口 8000)...")
|
||||
runserver_cmd = ["uv", "run", "manage.py", "runserver", "0.0.0.0:8000"]
|
||||
runserver_process = subprocess.Popen(
|
||||
runserver_cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
universal_newlines=True,
|
||||
)
|
||||
processes.append(("Django Runserver", runserver_process))
|
||||
|
||||
# 等待一下,让 runserver 先启动
|
||||
time.sleep(1)
|
||||
|
||||
# 启动 Daphne (端口 8001)
|
||||
print("[*] 启动 Daphne WebSocket 服务器 (端口 8001)...")
|
||||
daphne_cmd = [
|
||||
python_exec,
|
||||
"-m",
|
||||
"daphne",
|
||||
"-b",
|
||||
"0.0.0.0",
|
||||
"-p",
|
||||
"8001",
|
||||
"oj.asgi:application",
|
||||
]
|
||||
daphne_process = subprocess.Popen(
|
||||
daphne_cmd,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
text=True,
|
||||
bufsize=1,
|
||||
universal_newlines=True,
|
||||
)
|
||||
processes.append(("Daphne", daphne_process))
|
||||
|
||||
print()
|
||||
print("[✓] 所有服务器已启动")
|
||||
print()
|
||||
|
||||
# 创建输出线程
|
||||
def print_output(name, process):
|
||||
"""打印进程输出"""
|
||||
for line in process.stdout:
|
||||
print(f"[{name}] {line}", end="")
|
||||
|
||||
# 启动输出线程
|
||||
threads = []
|
||||
for name, process in processes:
|
||||
thread = Thread(target=print_output, args=(name, process), daemon=True)
|
||||
thread.start()
|
||||
threads.append(thread)
|
||||
|
||||
# 等待进程(任意一个退出就退出)
|
||||
while True:
|
||||
for name, process in processes:
|
||||
if process.poll() is not None:
|
||||
print(f"\n[!] {name} 已退出")
|
||||
raise KeyboardInterrupt
|
||||
time.sleep(0.5)
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print()
|
||||
print()
|
||||
print("[*] 正在停止所有服务器...")
|
||||
|
||||
# 终止所有进程
|
||||
for name, process in processes:
|
||||
try:
|
||||
if process.poll() is None: # 如果进程还在运行
|
||||
print(f"[*] 停止 {name}...")
|
||||
if is_windows:
|
||||
# Windows 使用 CTRL_C_EVENT
|
||||
process.send_signal(signal.CTRL_C_EVENT)
|
||||
else:
|
||||
# Unix 使用 SIGTERM
|
||||
process.terminate()
|
||||
|
||||
# 等待进程结束(最多 5 秒)
|
||||
try:
|
||||
process.wait(timeout=5)
|
||||
except subprocess.TimeoutExpired:
|
||||
print(f"[!] {name} 未响应,强制终止...")
|
||||
process.kill()
|
||||
process.wait()
|
||||
except Exception as e:
|
||||
print(f"[!] 停止 {name} 时出错: {e}")
|
||||
|
||||
print()
|
||||
print("[✓] 所有服务器已停止")
|
||||
|
||||
except Exception as e:
|
||||
print(f"[✗] 错误: {e}")
|
||||
|
||||
# 清理所有进程
|
||||
for name, process in processes:
|
||||
try:
|
||||
if process.poll() is None:
|
||||
process.kill()
|
||||
process.wait()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user