Files
ykxmz/_build/patch_server_relay.py
T
xmz7891 b62ac865ea ykxmz 1.5.0:修复手表端 TLS 证书校验 + MTU 修复网络稳定性
被控端
- 修复 MTU 问题:夹 MSS + 路径 MTU 探测(公网可用率 48% -> 100%)
- 复用 HTTP 连接(免掉每次新建 TLS 的 30% 握手失败)
- 每分钟回头找局域网,自动切回快 400 倍的路径
- 画面心跳帧:静止时省流量,客户端仍知道流是活的
- 锁屏时给出可操作的提示

手表端
- 内置 GTS Root R4 / GlobalSign Root CA,修 SSLHandshakeException
- 连接错误翻译成人话(证书/时间/解析/超时分别提示)
- 经中转连上后用服务器报的地址刷新已配对记录
- 新增局域网连接页面、服务器延迟检测

服务器端
- 支持 chunked 请求体(修每 16 秒一次的连接错乱与大面积 502)
- 网络调优脚本 net-tune.sh(开机自动应用)
- 管理页:批量删除、网络体检、下载区
- 隧道改 HTTP/2 + 双连接

文档
- 许可协议 / 安装前必读 / 安装后须知(作者:小麦子)
2026-10-06 19:01:05 +08:00

149 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""把中转接进服务端。
核心思路:中转连接伪装成一条普通 TCP 连接。
Session(conn) 里的 conn 只要支持 recv / sendall / settimeout / close,
就能照常跑。RelaySocket 正好实现了这几个方法。
所以在 _accept_loop 之外,再加一条入口:
中转说"有手表接入" -> 造一个 RelaySocket -> 照样 new Session -> 跑同一个
_client_loop。原来的配对、令牌校验、权限判断**全部不用改**。
数据流:
手表的字节 -> 中转 -> RelayLink 长轮询 -> RelaySocket.feed()
-> Session.recv() -> 命令处理 -> Session.send() -> RelaySocket.sendall()
-> RelayLink POST -> 中转 -> 手表
"""
from __future__ import annotations
import sys
from pathlib import Path
SERVER = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\windows"
r"\lanremote\server.py")
# ---------------- 1. 接入中转连接 + 生命周期 ----------------
ANCHOR = " # ---------------- 接受连接 ----------------"
NEW = ''' # ---------------- 中转(跨网络)----------------
def adopt_relay_socket(self, relay_socket) -> None:
"""把一条中转连接当成普通 TCP 连接接纳进来。
中转那边说"有手表接入了",这里就造一个 Session 跑同样的
_client_loop —— 上面的协议、配对、鉴权一行都不用改。
"""
address = ("中转服务器", 0)
session = Session(relay_socket, address, self)
with self._lock:
self.sessions.append(session)
self._log("设备接入(经中转,跨网络)")
self._notify_ui()
threading.Thread(target=self._client_loop, args=(session,),
name="client-relay", daemon=True).start()
def enable_relay(self, url: str = "") -> bool:
"""启用中转。地址优先用参数,其次读设置。"""
from .relay import RelayLink
target = (url or "").strip() or str(self.store.get("relay_url") or "")
if not target.strip():
return False
if self._relay is not None:
return True
self._relay = RelayLink(self.store, log=self._log,
on_session=self.adopt_relay_socket)
started = self._relay.start(target)
if started:
self._log(f"已启用中转:{self._relay.url} 配对码 {self.store.pairing_code()}")
return started
def relay_status(self) -> dict:
if self._relay is None:
return {"enabled": False}
return self._relay.status()
def _stop_relay(self) -> None:
if self._relay is None:
return
try:
self._relay.stop()
except Exception: # noqa: BLE001
pass
self._relay = None
# ---------------- 接受连接 ----------------'''
# ---------------- 2. start() 里自动启用 ----------------
START_OLD = ''' self._sock = sock
self._running = True'''
START_NEW = ''' self._sock = sock
self._running = True
# 配了中转地址就同时启用跨网络通道(和局域网监听并存,不冲突)
try:
self.enable_relay()
except Exception as exc: # noqa: BLE001
self._log(f"启用中转失败:{exc}")'''
# ---------------- 3. stop() 里停掉 ----------------
STOP_OLD = ''' def stop(self) -> None:
self._running = False
self._stop_streamer()'''
STOP_NEW = ''' def stop(self) -> None:
self._running = False
self._stop_relay()
self._stop_streamer()'''
# ---------------- 4. __init__ 里加字段 ----------------
INIT_OLD = ''' self._lock = threading.RLock()'''
INIT_NEW = ''' self._lock = threading.RLock()
# 跨网络中转链路(配了 relay_url 才会启用)
self._relay = None'''
def main() -> int:
text = SERVER.read_text(encoding="utf-8")
ok = True
if "adopt_relay_socket" in text:
print(" 已经接过中转,跳过")
return 0
for old, new, tag in ((ANCHOR, NEW, "中转接入 + 生命周期方法"),
(START_OLD, START_NEW, "start() 自动启用中转"),
(STOP_OLD, STOP_NEW, "stop() 停掉中转"),
(INIT_OLD, INIT_NEW, "__init__ 加 _relay 字段")):
if old not in text:
print(f" [失败] {tag} —— 锚点没找到")
ok = False
continue
text = text.replace(old, new, 1)
print(f" {tag}")
SERVER.write_text(text, encoding="utf-8")
# 先确认 self._lock 是在 __init__ 里赋值的,别改错地方
import ast
try:
ast.parse(text)
print(" server.py 语法 OK")
except SyntaxError as exc:
print(f" server.py 语法错误: {exc}")
ok = False
return 0 if ok else 1
if __name__ == "__main__":
sys.exit(main())