mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 23:00:44 +00:00
用户报两个问题:
1. 局域网能搜到电脑,IP/端口/配对码都对,点连接**没有任何反应**
2. 走中转 1426ms 延时,一会儿就 502
========== 一、局域网被劫持(真 bug)==========
MainActivity.connect() 里:
boolean usedLan = !relayUrl().isEmpty() ? false : true;
if (!relay.isEmpty()) {
reply = client.connectViaRelay(...); // 走中转
} else {
reply = client.connect(host, port, ...); // 才走局域网
}
**只看「中转设置里填没填地址」,填了就一律走中转,
完全无视用户填的局域网 IP 和端口。**
而中转单次超时是 40 秒 —— 用户点完就卡在「正在连接…」
四十秒,在他看来就是"没有任何反应"。
影响两条路:
* 「局域网连接」页面填 IP 直连(connectLanTyped)
* 首页「已配对的电脑」点一下重连(quickConnect)
修法:给 connect() 加 preferLan 参数。明确要走局域网时
**先直连(6 秒超时,局域网本该是毫秒级),失败再退回中转**,
保证最终能连上。
顺带两个体验改进:
* 设备列表里,保存的 IP 和手表不同网段时标「⚠ 地址可能已过期」
(用户截图里那个 192.168.2.64 就是过期地址,电脑早换成
192.168.10.103 了)
* quickConnect 判断出地址过期就跳过直连,直接走中转查最新地址 ——
省掉那 6 秒白等
========== 二、长轮询 15 秒 -> 60 秒 ==========
实测隧道每次请求要多花 1~2 秒(CF 边缘路由 + 回源):
本机直连 60 秒的 poll -> 60.0s
走公网同一个 poll -> 61.5~62.0s
这个开销是**按次数**收的:
15 秒一循环 -> 一天 5760 次/端,光路费 2.4~3.2 小时
60 秒一循环 -> 一天 1440 次/端,光费 0.6~0.8 小时
而且请求越频繁,撞上丢包/重连窗口的概率越大。
**不会让命令变慢**:长轮询是"有数据立刻返回"(device.event 唤醒),
拉长只是减少空转重开。实测 60 秒长轮询穿隧道 4/4 通过;
Cloudflare 单请求上限 100 秒,留了 40 秒余量。
三层同步改(客户端超时必须显著大于服务端 hold):
* relay/relay.py RELAY_POLL 默认 25 -> 60
* windows/lanremote/relay.py POLL_TIMEOUT 40 -> 90
* android .../RelayTransport.java POLL_TIMEOUT_MS 40000 -> 90000
========== 三、A/B 实测(还在跑更严谨的一轮)==========
短测发现基线 http2+4 虽然 100% 成功,但 **P90 是 16.8 秒**
(每 10 次有 1 次卡十几秒 —— 正是用户说的"没反应"),
而 quic+6 的 P90 只有 2.8 秒。正在用真实长轮询模式
跑 10 分钟对照确认。
71 lines
2.8 KiB
Bash
71 lines
2.8 KiB
Bash
#!/bin/bash
|
|
# 看隧道当前配置,并做一轮协议/连接数的对照实测。
|
|
set -u
|
|
|
|
echo "════════ 1. 隧道服务当前参数 ════════"
|
|
grep -E 'ExecStart' /etc/systemd/system/lanremote-tunnel.service | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 2. cloudflared 版本 & 支持的参数 ════════"
|
|
cloudflared --version 2>&1 | head -1 | sed 's/^/ /'
|
|
echo " --- 和丢包恢复相关的参数:"
|
|
cloudflared tunnel run --help 2>&1 | grep -E 'protocol|ha-connections|edge-ip-version|region|retries' | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 3. 当前落点 ════════"
|
|
curl -s --max-time 5 http://127.0.0.1:20241/metrics 2>/dev/null \
|
|
| grep 'server_locations.*} 1' | sed 's/^/ /'
|
|
|
|
echo
|
|
echo "════════ 4. 测一轮公网(12 次,记录耗时分布)════════"
|
|
times=()
|
|
ok=0
|
|
for i in $(seq 1 12); do
|
|
out=$(curl -s -o /dev/null -w '%{http_code} %{time_total}' --max-time 25 \
|
|
-H 'User-Agent: LanRemote/1.8.0' https://relay.xxmxxs.top/v1/health)
|
|
code=$(echo "$out" | awk '{print $1}')
|
|
ms=$(echo "$out" | awk '{printf "%d", $2*1000}')
|
|
times+=("$ms")
|
|
[ "$code" = "200" ] && ok=$((ok+1))
|
|
printf " %2d: HTTP %-4s %5sms\n" "$i" "$code" "$ms"
|
|
sleep 1
|
|
done
|
|
echo " 可用 $ok/12"
|
|
echo " 耗时: $(printf '%s\n' "${times[@]}" | sort -n | awk '{a[NR]=$1} END {printf "最小 %dms 中位 %dms 最大 %dms", a[1], a[int(NR/2)+1], a[NR]}')"
|
|
|
|
echo
|
|
echo "════════ 5. 每个候选 edge IP 的可达性(挑最快的)════════"
|
|
python3 - <<'PY'
|
|
import socket, time
|
|
ips = ["198.41.192.47", "198.41.192.57", "198.41.192.67", "198.41.192.107",
|
|
"198.41.192.167", "198.41.192.227", "198.41.200.23", "198.41.200.33",
|
|
"198.41.200.43", "198.41.200.63", "198.41.200.113", "198.41.200.193"]
|
|
rows = []
|
|
for ip in ips:
|
|
s = socket.socket(); s.settimeout(4)
|
|
t = time.perf_counter()
|
|
try:
|
|
s.connect((ip, 7844))
|
|
ms = (time.perf_counter() - t) * 1000
|
|
rows.append((ms, ip, "通"))
|
|
except OSError as e:
|
|
rows.append((99999, ip, "不通"))
|
|
finally:
|
|
s.close()
|
|
rows.sort()
|
|
for ms, ip, st in rows:
|
|
if st == "通":
|
|
print(" %-16s %6.0f ms" % (ip, ms))
|
|
else:
|
|
print(" %-16s 不通" % ip)
|
|
good = [r for r in rows if r[2] == "通"]
|
|
print(" => %d/%d 可达,最快 %s" % (len(good), len(rows), good[0][1] if good else "无"))
|
|
PY
|
|
|
|
echo
|
|
echo "════════ 6. 隧道日志里 i/o timeout 的最近频率 ════════"
|
|
for kw in 'Registered tunnel connection' 'Lost connection' 'i/o timeout' 'context deadline'; do
|
|
n=$(tail -800 /root/lanremote-relay/tunnel.log 2>/dev/null | grep -c "$kw")
|
|
printf " %-34s %s 次(最近 800 行)\n" "$kw" "$n"
|
|
done
|