Commit Graph
5 Commits
Author SHA1 Message Date
xmz7891 d4f335b8f9 管理页新增:允许/禁止新设备接入 + 修改设备配对码
== 功能一:允许新设备接入开关 ==

关掉之后只有已经登记过的电脑能继续上线,没见过的新设备一律拒绝。
状态存在 relay_state.json 里,重启不丢。

判断新设备用的是 deviceId,不是配对码 ——
这一点很关键:管理员给老设备改过码之后,
那台设备必须仍然能进来;按码判断的话它会被自己的开关挡在外面。
测试里专门有一条 A3b 守这个行为。

被拒时回 blocked=True,让客户端能区分被管理员挡了
和配对码冲突,而不是去匹配中文错误文案(文案一改就坏)。

== 功能二:修改任意设备的配对码 ==

管理页每台设备一个「改码」按钮,填 6 位数字即生效。
要点:
  * 新旧码冲突检查
  * 旧码映射必须删掉,否则变成孤儿条目,
    管理页配对码占用的数字会虚高
  * 改码踢掉该设备当前会话(会话绑在码上)
  * 立刻持久化

== 顺手修掉两个真 bug ==

1. 改码功能一上线就 500:Session 用了 __slots__,
   根本没有 session_id 属性(会话是以 token 为 key 存在 dict 里的),
   写 s.session_id 直接 AttributeError。
   改成遍历 sessions.items() 拿 key。

2. snapshot() 里有同样的错(清理超时设备那段):
   平时 stale 列表是空的所以从没炸过,一旦真有设备超过 6 小时
   没上报就会 500。这次一起修了。

== 管理页 UI ==
  * 设备小节加了「允许新设备接入」勾选框
  * 每行加「改码」按钮(走 prompt,不引入弹窗层)
  * 改码按钮用 data-recode 而不是 data-device ——
    现有单台删除按 button.danger[data-device] 绑,
    带上 data-device 会被当成删除按钮,点改码变删设备。
    测试 C6 专门断言这一点。

== 测试 ==
新增 _tests/test_admin_device_control.py(23 项),
已注册进 _tests/verify_all.ps1 第 3e 阶段。
2026-10-07 17:01:14 +08:00
xmz7891 25e7780272 单次请求失败不再立刻判离线,改成连续 3 次
实测单个请求有 2~4% 的偶发失败(4G 丢包打在一条隧道连接上,
或者那条连接正在重连)。原逻辑是一失败就 online = false,
于是界面上会闪一下已断开 —— 用户点按钮时正好撞上那一闪,
看起来就像又连不上了。

而链路其实 1.5~15 秒就自己恢复(客户端本来就有退避重试)。

改成连续失败 3 次才判离线(手表至少 4.5 秒、电脑至少 6 秒):
  * 单次抖动完全不影响界面
  * 真的断了仍然如实显示

这不是掩盖问题,而是把是否可用的判断从一次采样改成连续采样 ——
单点采样在有丢包的链路上噪声太大。

两边同步改:
  android .../RelayTransport.java   failStreak + OFFLINE_AFTER
  windows/lanremote/relay.py        _fail_streak + OFFLINE_AFTER

顺带记录 PC 端基准(真实用户视角,之前都是在设备上量的,
那等于把设备 4G 算了两遍):
  公网可用率 98%   耗时 中位 911  P90 1889  P99 23868 ms
  长轮询     5/6   耗时 60.8~62.1 秒
对比设备端(中位 1344 / P90 2563)—— 用户实际体验比设备端量出来的好。
2026-10-07 16:16:50 +08:00
xmz7891 bf15a2ee61 静态资源交给 Cloudflare 边缘缓存(下载提速 41 倍)
实测基线:
  ykxmz-setup-1.8.1.exe   只下到 237568/15067199 字节就停(17 KB/s)
  ykxmz-watch-1.8.1.apk   201523 字节 / 66.8 秒 = 3 KB/s
  ykxmz-server-1.8.1.zip  214900 字节 / 3.1 秒  = 67 KB/s

原因:relay 给所有响应都发 Cache-Control: no-store,
Cloudflare 完全不缓存 —— 每次下载/每张图都要穿隧道回 4G 源站。

改动:
  /download/*   no-store -> public, max-age=604800, immutable
                文件名带版本号,同一名字内容永不改变,可以长缓存
  /             -> public, max-age=60(挡住刷新重复回源)
  /favicon.ico  已是 max-age=86400,保持不变
  /shot/*       已是 max-age=86400,保持不变
  /v1/*         保持 no-store(接口必须实时)

顺带修两个自己踩的坑:

1. _send() 无条件先发 no-store,再追加 extra 里的 Cache-Control,
   结果是**两个 Cache-Control 头**,客户端只认第一个 ——
   调用方传的缓存策略被吃掉。改成 extra 里有就不再发默认值。

2. do_HEAD 和 do_GET 的缓存头不一致:HEAD 对非 /shot/ 一律报 no-store。
   下载器/代理用 HEAD 探测时会误判文件不可缓存。
   现在 _head_info 给每个路由带上和 GET 完全相同的缓存头,
   do_HEAD 也不再盲目覆盖。

结果(同一个测试口径):
  setup.exe  17 KB/s(截断) -> 695 KB/s 完整 15 MB   41 倍
  watch.apk   3 KB/s         -> 101 KB/s              33 倍
  server.zip 67 KB/s         ->  87 KB/s
  三个文件全部 cf-cache-status=HIT(不再穿隧道回源)

排查过程记一笔:我一开始用 curl -I 验证,
看到的全是 no-store —— 因为 **-I 发的是 HEAD**,
而 HEAD 走的是另一个分支。查了半天才发现是验证方法错了。
2026-10-07 15:44:48 +08:00
xmz7891 65dc2fad65 1.6.1:常规发布
- 版本号 1.6.1 -> 1.6.1
- 重建三端并打包
- 关键测试全过
2026-10-06 23:08:07 +08:00
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