156 lines
4.5 KiB
Bash
Executable File
156 lines
4.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# SDK 连接监视器(无 USB 依赖)— 探测 NAS/Docker/frp 可达性,写 active_sdk.env,监控 WS 在线
|
||
# 用法:
|
||
# bash sdk/scripts/sdk_connection_watcher.sh --once
|
||
# bash sdk/scripts/sdk_connection_watcher.sh --bg
|
||
# bash sdk/scripts/install_sdk_watcher_launchagent.sh
|
||
set -euo pipefail
|
||
|
||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
SDK_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||
DEVICE_ID="${DEVICE_ID:-xgfe65eimrrofyws}"
|
||
SDK_PORT="${WORKPHONE_SDK_PORT:-8899}"
|
||
INTERVAL="${WATCHER_INTERVAL:-20}"
|
||
FAST_INTERVAL="${WATCHER_FAST_INTERVAL:-10}"
|
||
ACTIVE_ENV="${SDK_ROOT}/config/active_sdk.env"
|
||
LOG="${SDK_ROOT}/logs/sdk_connection_watcher.log"
|
||
PID_FILE="${SDK_ROOT}/logs/sdk_connection_watcher.pid"
|
||
BUILD_CFG="${SCRIPT_DIR}/build_agent_config.py"
|
||
|
||
mkdir -p "${SDK_ROOT}/logs" "${SDK_ROOT}/config"
|
||
log() { echo "[$(date '+%F %T')] $*" | tee -a "$LOG"; }
|
||
|
||
health_ok() {
|
||
curl -sf --max-time 3 "http://$1:${SDK_PORT}/health" >/dev/null 2>&1
|
||
}
|
||
|
||
pick_sdk_url() {
|
||
local h url=""
|
||
for h in 192.168.110.101 192.168.1.201; do
|
||
if health_ok "$h"; then
|
||
url="http://${h}:${SDK_PORT}"
|
||
echo "$url"
|
||
return 0
|
||
fi
|
||
done
|
||
local mac_ip
|
||
mac_ip=$(python3 -c "
|
||
import subprocess
|
||
o=subprocess.check_output(['ifconfig'], text=True)
|
||
for line in o.splitlines():
|
||
p=line.strip().split()
|
||
if len(p)>=2 and p[0]=='inet' and not p[1].startswith('127.'):
|
||
if p[1].startswith('192.168.') or p[1].startswith('10.'):
|
||
print(p[1]); break
|
||
" 2>/dev/null || echo "")
|
||
if [[ -n "$mac_ip" ]] && health_ok "$mac_ip"; then
|
||
echo "http://${mac_ip}:${SDK_PORT}"
|
||
return 0
|
||
fi
|
||
if health_ok "open.quwanzhi.com"; then
|
||
echo "http://open.quwanzhi.com:${SDK_PORT}"
|
||
return 0
|
||
fi
|
||
echo "http://192.168.110.101:${SDK_PORT}"
|
||
}
|
||
|
||
ws_count() {
|
||
local base="$1"
|
||
curl -s --max-time 5 "${base}/api/v3/connection/status" 2>/dev/null | \
|
||
python3 -c "import sys,json;d=json.load(sys.stdin).get('data',{});print(d.get('online_ws_count',0))" 2>/dev/null || echo 0
|
||
}
|
||
|
||
device_online() {
|
||
local base="$1"
|
||
curl -s --max-time 5 "${base}/api/v3/connection/status" 2>/dev/null | \
|
||
python3 -c "
|
||
import sys,json
|
||
d=json.load(sys.stdin).get('data',{})
|
||
ids=d.get('online_device_ids') or []
|
||
print(1 if '${DEVICE_ID}' in ids else 0)
|
||
" 2>/dev/null || echo 0
|
||
}
|
||
|
||
write_active_env() {
|
||
local url="$1"
|
||
local ws="$2"
|
||
local tier="unknown"
|
||
case "$url" in
|
||
*192.168.110.101*|*192.168.1.201*) tier="nas_lan" ;;
|
||
*open.quwanzhi.com*) tier="nas_frp" ;;
|
||
*) tier="mac_docker" ;;
|
||
esac
|
||
cat >"$ACTIVE_ENV" <<EOF
|
||
# auto $(date '+%F %T') sdk_connection_watcher
|
||
export WORKPHONE_SDK_URL=${url}
|
||
export WORKPHONE_SDK_TIER=${tier}
|
||
export WORKPHONE_WS_ONLINE=${ws}
|
||
export WORKPHONE_DEVICE_ID=${DEVICE_ID}
|
||
EOF
|
||
}
|
||
|
||
watcher_once() {
|
||
local url ws dev
|
||
url="$(pick_sdk_url)"
|
||
ws="$(ws_count "$url")"
|
||
dev="$(device_online "$url")"
|
||
write_active_env "$url" "$ws"
|
||
export WORKPHONE_SDK_URL="$url"
|
||
|
||
if [[ "$dev" == "1" ]]; then
|
||
log "OK tier=$(grep TIER "$ACTIVE_ENV" | cut -d= -f2) sdk=${url} ws=${ws} device=${DEVICE_ID} online"
|
||
return 0
|
||
fi
|
||
|
||
if [[ "$ws" -ge 1 ]]; then
|
||
log "WARN sdk=${url} ws=${ws} but ${DEVICE_ID} not in list"
|
||
return 0
|
||
fi
|
||
|
||
log "OFFLINE sdk=${url} ws=0 — 手机 Termux Agent 应自主寻服重连(无需 Mac USB)"
|
||
# 若有 ADB 则尝试 OTA 推配置+拉起(可选,不阻塞)
|
||
if command -v adb >/dev/null 2>&1; then
|
||
local serial
|
||
serial=$(adb devices 2>/dev/null | awk '/\tdevice$/{print $1; exit}')
|
||
if [[ -n "$serial" ]]; then
|
||
log "ADB 可用 ${serial} → OTA termux_push"
|
||
DEVICE_SERIAL="$serial" DEVICE_ID="$DEVICE_ID" \
|
||
bash "${SCRIPT_DIR}/termux_push_and_start_agent.sh" >>"$LOG" 2>&1 || true
|
||
ws="$(ws_count "$url")"
|
||
write_active_env "$url" "$ws"
|
||
[[ "$ws" -ge 1 ]] && log "OTA ok ws=${ws}" && return 0
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
watcher_loop() {
|
||
log "sdk_connection_watcher start interval=${INTERVAL}s device=${DEVICE_ID}"
|
||
while true; do
|
||
if watcher_once; then
|
||
sleep "$INTERVAL"
|
||
else
|
||
sleep "$FAST_INTERVAL"
|
||
fi
|
||
done
|
||
}
|
||
|
||
case "${1:-}" in
|
||
--once) watcher_once ;;
|
||
--bg)
|
||
if [[ -f "$PID_FILE" ]] && kill -0 "$(cat "$PID_FILE")" 2>/dev/null; then
|
||
echo "已在运行 PID $(cat "$PID_FILE")"
|
||
exit 0
|
||
fi
|
||
nohup bash "$0" >>"$LOG" 2>&1 &
|
||
echo $! >"$PID_FILE"
|
||
echo "sdk_connection_watcher 后台 PID $(cat "$PID_FILE")"
|
||
;;
|
||
--stop)
|
||
[[ -f "$PID_FILE" ]] && kill "$(cat "$PID_FILE")" 2>/dev/null || true
|
||
rm -f "$PID_FILE"
|
||
echo "已停止"
|
||
;;
|
||
*) watcher_loop ;;
|
||
esac
|