This commit is contained in:
root
2026-05-17 14:06:06 +00:00
parent a3e8a4a96c
commit a91188ca68
29 changed files with 442 additions and 58 deletions

View File

@@ -486,6 +486,41 @@ def _env_flag(env: dict[str, str], key: str, default: bool = True) -> bool:
return raw not in {"0", "false", "no", "off", "disable", "disabled"}
def _env_int(env: dict[str, str], key: str, default: int) -> int:
raw = str(env.get(key, "")).strip()
if not raw:
return default
try:
return int(raw)
except ValueError:
return default
def _neko_http_ports(env: dict[str, str]) -> list[int]:
return [
_env_int(env, "NEKO_HTTP_PORT_1", _env_int(env, "NEKO_HTTP_PORT", 9200)),
_env_int(env, "NEKO_HTTP_PORT_2", 9201),
_env_int(env, "NEKO_HTTP_PORT_3", 9202),
]
def _neko_instances(mdns_host: str, env: dict[str, str]) -> list[dict[str, Any]]:
instances: list[dict[str, Any]] = []
for idx, port in enumerate(_neko_http_ports(env), start=1):
url = f"http://{mdns_host}:{port}"
instances.append(
{
"id": idx,
"label": f"Neko {idx}",
"port": port,
"url": url,
"quick_link_key": "neko_browser" if idx == 1 else f"neko_browser_{idx}",
"alias_keys": ["neko_browser_1"] if idx == 1 else [],
}
)
return instances
def _probe_tcp_port(host: str, port: int, timeout: float = 2.0) -> dict[str, Any]:
t0 = time.monotonic()
try:
@@ -813,13 +848,9 @@ def recent_pm2_log_lines(max_lines: int = 14) -> list[str]:
async def stack_stream_probes() -> dict[str, Any]:
"""本机 SRS / Neko HTTP 端口探测(供 live.local 验收)。"""
env = load_stack_env()
srs_p = int(env.get("SRS_HTTP_PORT", "8080") or 8080)
srs_api_p = int(env.get("SRS_API_PORT", "1985") or 1985)
neko_ports = [
int(env.get("NEKO_HTTP_PORT_1") or env.get("NEKO_HTTP_PORT", "9200") or 9200),
int(env.get("NEKO_HTTP_PORT_2", "9201") or 9201),
int(env.get("NEKO_HTTP_PORT_3", "9202") or 9202),
]
srs_p = _env_int(env, "SRS_HTTP_PORT", 8080)
srs_api_p = _env_int(env, "SRS_API_PORT", 1985)
neko_ports = _neko_http_ports(env)
loop = asyncio.get_event_loop()
def run_srs() -> dict[str, Any]:
@@ -877,9 +908,7 @@ def stack_summary() -> dict:
srs_rtmp = env.get("SRS_RTMP_PORT", "1935")
android_panel = env.get("ANDROID_PANEL_PORT", "5000")
chrome_dbg = env.get("BROWSER_REMOTE_DEBUG_PORT", "9222")
neko_port = env.get("NEKO_HTTP_PORT_1") or env.get("NEKO_HTTP_PORT", "9200")
neko_port_2 = env.get("NEKO_HTTP_PORT_2", "9201")
neko_port_3 = env.get("NEKO_HTTP_PORT_3", "9202")
neko_instances = _neko_instances(mdns_host, env)
redroid_port = env.get("REDROID_DEFAULT_PORT", "5555")
mitmproxy_port = env.get("MITMPROXY_WEB_PORT", "8086")
vscode_port = env.get("VSCODE_SERVER_PORT", "8440")
@@ -900,14 +929,16 @@ def stack_summary() -> dict:
"srs_api": f"http://{mdns_host}:{srs_api}/api/v1/versions",
"ws_scrcpy": f"{control_url}/android",
"chromium_remote_debug": f"http://{mdns_host}:{chrome_dbg}",
"neko_browser": f"http://{mdns_host}:{neko_port}",
"neko_browser_2": f"http://{mdns_host}:{neko_port_2}",
"neko_browser_3": f"http://{mdns_host}:{neko_port_3}",
"redroid_adb": f"{mdns_host}:{redroid_port}",
"pulseaudio_tcp": f"{mdns_host}:{pulseaudio_port}",
"openclaw": f"http://{mdns_host}:{openclaw_port}",
"services_console": f"{control_url}/?view=services",
}
for instance in neko_instances:
quick_link_key = str(instance["quick_link_key"])
ql[quick_link_key] = str(instance["url"])
for alias_key in instance.get("alias_keys") or []:
ql[str(alias_key)] = str(instance["url"])
return {
"hostname": hostname,
"mdns_host": mdns_host,
@@ -919,6 +950,7 @@ def stack_summary() -> dict:
"dashboard_url": f"http://{mdns_host}" if homepage_port in {"80", ""} else f"http://{mdns_host}:{homepage_port}",
"control_url": f"http://{mdns_host}:{web_port}",
"stack_env_present": STACK_ENV.is_file(),
"neko_instances": neko_instances,
"neko_login": {
"user_login": "live",
"user_password": env.get("NEKO_USER_PASS", "12345678"),