#!/bin/bash # RTC Backend 启动脚本(同时启动 Django + hw_service_go) DJANGO_PORT=${1:-8000} WS_PORT=${2:-8888} PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)" VENV_PYTHON="$PROJECT_DIR/venv/bin/python" GO_SERVICE_DIR="$PROJECT_DIR/hw_service_go" echo "=== RTC Backend 启动脚本 ===" echo "Django 端口: $DJANGO_PORT" echo "WebSocket 端口: $WS_PORT" echo "项目: $PROJECT_DIR" echo "" # ---- 检查 Go 环境 ---- GO_BIN=$(which go 2>/dev/null) if [ -z "$GO_BIN" ]; then # Homebrew 安装的 Go 不在默认 PATH,尝试常见位置 for candidate in \ /opt/homebrew/bin/go \ /usr/local/go/bin/go \ /opt/homebrew/Cellar/go/*/libexec/bin/go; do if [ -x "$candidate" ]; then GO_BIN="$candidate" break fi done fi if [ -z "$GO_BIN" ]; then echo "[x] 未找到 go 命令,请安装 Go 或检查 PATH" exit 1 fi echo "[✓] Go: $GO_BIN" # ---- 检查虚拟环境 ---- if [ ! -f "$VENV_PYTHON" ]; then echo "[x] 未找到虚拟环境: $VENV_PYTHON" exit 1 fi echo "[✓] 虚拟环境就绪" # ---- 释放占用端口的函数 ---- free_port() { local port=$1 local name=$2 local pids pids=$(lsof -ti :"$port" 2>/dev/null) if [ -z "$pids" ]; then echo "[✓] 端口 $port 空闲" return fi echo "[!] 端口 $port ($name) 被占用,PID: $pids,正在终止..." echo "$pids" | xargs kill -9 2>/dev/null for i in 1 2 3; do sleep 1 pids=$(lsof -ti :"$port" 2>/dev/null) [ -z "$pids" ] && break echo "$pids" | xargs kill -9 2>/dev/null done if [ -n "$(lsof -ti :"$port" 2>/dev/null)" ]; then echo "[x] 端口 $port 释放失败,请手动处理" exit 1 fi echo "[✓] 端口 $port 已释放" } free_port "$DJANGO_PORT" "Django" free_port "$WS_PORT" "hw_service_go" # ---- 退出时清理所有子进程 ---- cleanup() { echo "" echo "=== 正在关闭所有服务... ===" kill "$DJANGO_PID" "$WS_PID" 2>/dev/null wait "$DJANGO_PID" "$WS_PID" 2>/dev/null echo "=== 所有服务已停止 ===" } trap cleanup SIGINT SIGTERM EXIT # ---- 启动 Django ---- echo "" echo "=== 启动 Django 开发服务器 (0.0.0.0:$DJANGO_PORT) ===" cd "$PROJECT_DIR" $VENV_PYTHON manage.py runserver "0.0.0.0:$DJANGO_PORT" & DJANGO_PID=$! echo "[✓] Django PID: $DJANGO_PID" # ---- 启动 hw_service_go ---- echo "" echo "=== 启动 hw_service_go WebSocket 服务 (0.0.0.0:$WS_PORT) ===" cd "$GO_SERVICE_DIR" HW_RTC_BACKEND_URL="http://localhost:$DJANGO_PORT" \ HW_WS_PORT="$WS_PORT" \ "$GO_BIN" run ./cmd/main.go & WS_PID=$! echo "[✓] hw_service_go PID: $WS_PID" echo "" echo "=== 所有服务已启动,按 Ctrl+C 停止 ===" echo " Django: http://localhost:$DJANGO_PORT" echo " WebSocket: ws://localhost:$WS_PORT/xiaozhi/v1/" echo " 健康检查: http://localhost:$WS_PORT/healthz" echo "" # 等待任意一个进程退出,然后触发 cleanup wait -n "$DJANGO_PID" "$WS_PID" 2>/dev/null || wait "$DJANGO_PID" "$WS_PID"