mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-19 16:30:43 +00:00
ykxmz 1.5.0锛氫慨澶嶆墜琛ㄧ TLS 璇佷功鏍¢獙 + MTU 淇缃戠粶绋冲畾鎬?
琚帶绔?- 淇 MTU 闂锛氬す MSS + 璺緞 MTU 鎺㈡祴锛堝叕缃戝彲鐢ㄧ巼 48% -> 100%锛?- 澶嶇敤 HTTP 杩炴帴锛堝厤鎺夋瘡娆℃柊寤?TLS 鐨?30% 鎻℃墜澶辫触锛?- 姣忓垎閽熷洖澶存壘灞€鍩熺綉锛岃嚜鍔ㄥ垏鍥炲揩 400 鍊嶇殑璺緞 - 鐢婚潰蹇冭烦甯э細闈欐鏃剁渷娴侀噺锛屽鎴风浠嶇煡閬撴祦鏄椿鐨?- 閿佸睆鏃剁粰鍑哄彲鎿嶄綔鐨勬彁绀? 鎵嬭〃绔?- 鍐呯疆 GTS Root R4 / GlobalSign Root CA锛屼慨 SSLHandshakeException - 杩炴帴閿欒缈昏瘧鎴愪汉璇濓紙璇佷功/鏃堕棿/瑙f瀽/瓒呮椂鍒嗗埆鎻愮ず锛?- 缁忎腑杞繛涓婂悗鐢ㄦ湇鍔″櫒鎶ョ殑鍦板潃鍒锋柊宸查厤瀵硅褰?- 鏂板灞€鍩熺綉杩炴帴椤甸潰銆佹湇鍔″櫒寤惰繜妫€娴? 鏈嶅姟鍣ㄧ - 鏀寔 chunked 璇锋眰浣擄紙淇瘡 16 绉掍竴娆$殑杩炴帴閿欎贡涓庡ぇ闈㈢Н 502锛?- 缃戠粶璋冧紭鑴氭湰 net-tune.sh锛堝紑鏈鸿嚜鍔ㄥ簲鐢級 - 绠$悊椤碉細鎵归噺鍒犻櫎銆佺綉缁滀綋妫€銆佷笅杞藉尯 - 闅ч亾鏀?HTTP/2 + 鍙岃繛鎺? 鏂囨。 - 璁稿彲鍗忚 / 瀹夎鍓嶅繀璇?/ 瀹夎鍚庨』鐭ワ紙浣滆€咃細灏忛害瀛愶級
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""中转管理器加「删除设备(连同配对码)」。
|
||||
|
||||
用户要求:
|
||||
"这个中转管理器,首先删除设备,就是删除设备并删除对应的配对码"
|
||||
|
||||
现状:
|
||||
/v1/admin/kick 只踢会话,设备还在,码还占着
|
||||
/v1/admin/forget 只抹配对码绑定,设备还挂在列表上
|
||||
两个都不是用户要的"删干净"。
|
||||
|
||||
新增:
|
||||
Relay.delete_device(device_id) —— 一次做完:
|
||||
1. 踢掉它的所有会话
|
||||
2. 删掉设备记录
|
||||
3. 删掉它的配对码绑定(这样那台设备下次可以重新设码)
|
||||
POST /v1/admin/delete {"deviceId": "..."} 或 {"code": "..."}
|
||||
POST /v1/admin/delete_all
|
||||
|
||||
管理页:
|
||||
每行加一个「删除」按钮(带二次确认)
|
||||
表格上方加一个「删除全部设备」按钮
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
RELAY = Path(r"C:\Users\shu\Desktop\deepseekagent\LanRemote\relay\relay.py")
|
||||
|
||||
# ---------------- 1. Relay.delete_device ----------------
|
||||
|
||||
DELETE_ANCHOR = ''' def forget(self, code: str) -> bool:'''
|
||||
|
||||
DELETE_NEW = ''' def delete_device(self, *, device_id: str = "", code: str = "") -> dict:
|
||||
"""删掉一台设备,**连同它的配对码绑定和所有会话**。
|
||||
|
||||
这就是管理页上「删除设备」按钮做的事。
|
||||
和 kick/forget 的区别:
|
||||
kick 只踢会话,设备还在,码还占着
|
||||
forget 只抹码绑定,设备还挂在列表上
|
||||
delete 三样一起清 —— 那台设备下次可以重新设任意配对码
|
||||
|
||||
返回做了什么,便于界面显示。
|
||||
"""
|
||||
target = None
|
||||
with self.lock:
|
||||
if device_id:
|
||||
target = self.devices.get(device_id)
|
||||
if target is None and code:
|
||||
owner = self.codes.get(code)
|
||||
if owner:
|
||||
target = self.devices.get(owner)
|
||||
device_id = owner
|
||||
if target is None:
|
||||
return {"ok": False, "error": "找不到这台设备"}
|
||||
|
||||
removed_sessions = self.kick(target.device_id)
|
||||
|
||||
with self.lock:
|
||||
self.devices.pop(target.device_id, None)
|
||||
# 把它的码绑定一起删掉
|
||||
gone_codes = [c for c, owner in list(self.codes.items())
|
||||
if owner == target.device_id]
|
||||
for item in gone_codes:
|
||||
self.codes.pop(item, None)
|
||||
# 清掉可能残留的会话记录
|
||||
for token in list(getattr(self, "sessions", {}).keys()):
|
||||
self.sessions.pop(token, None)
|
||||
self.save_state()
|
||||
|
||||
log(f"管理操作:删除设备 {target.name}(码 {target.code}),"
|
||||
f"踢掉 {removed_sessions} 个会话,清掉 {len(gone_codes)} 条码绑定")
|
||||
return {
|
||||
"ok": True,
|
||||
"deleted": target.device_id,
|
||||
"name": target.name,
|
||||
"code": target.code,
|
||||
"kicked": removed_sessions,
|
||||
"codesCleared": gone_codes,
|
||||
}
|
||||
|
||||
def forget(self, code: str) -> bool:'''
|
||||
|
||||
# ---------------- 2. 管理接口 ----------------
|
||||
|
||||
API_ANCHOR = ''' if path == "/v1/admin/forget":'''
|
||||
|
||||
API_NEW = ''' if path in ("/v1/admin/delete", "/v1/admin/delete_all"):
|
||||
body = self._json_body()
|
||||
if path == "/v1/admin/delete_all":
|
||||
# 一次删光(清场用)
|
||||
with RELAY.lock:
|
||||
all_ids = list(RELAY.devices.keys())
|
||||
results = [RELAY.delete_device(device_id=item)
|
||||
for item in all_ids]
|
||||
done = [r for r in results if r.get("ok")]
|
||||
log(f"管理操作:删除全部设备,共 {len(done)} 台")
|
||||
self._json(200, {"ok": True, "deleted": len(done),
|
||||
"devices": done})
|
||||
return
|
||||
|
||||
device = str(body.get("deviceId") or "").strip()
|
||||
code = str(body.get("code") or "").strip()
|
||||
if not device and not code:
|
||||
self._json(400, {"ok": False,
|
||||
"error": "要给 deviceId 或 code"})
|
||||
return
|
||||
result = RELAY.delete_device(device_id=device, code=code)
|
||||
self._json(200 if result.get("ok") else 404, result)
|
||||
return
|
||||
|
||||
if path == "/v1/admin/forget":'''
|
||||
|
||||
# ---------------- 3. 管理页:设备行加删除按钮 ----------------
|
||||
|
||||
ROW_OLD = ''' f'<td>{_kb(device["bytesIn"])} / {_kb(device["bytesOut"])}</td>'
|
||||
"</tr>")'''
|
||||
|
||||
ROW_NEW = ''' f'<td>{_kb(device["bytesIn"])} / {_kb(device["bytesOut"])}</td>'
|
||||
# 删除按钮:连同配对码一起删掉。
|
||||
# 用 data-* 传值,避免设备名里有引号把 HTML 弄坏。
|
||||
'<td><button class=del '
|
||||
f'data-device="{_esc(device["deviceId"])}" '
|
||||
f'data-name="{_esc(device["name"])}" '
|
||||
f'data-code="{_esc(device["code"])}">删除</button></td>'
|
||||
"</tr>")'''
|
||||
|
||||
TABLE_OLD = '''<table><tr><th>设备</th><th>配对码</th><th>会话</th><th>空闲</th>
|
||||
<th>待发(表/机)</th><th>流量(入/出)</th></tr>
|
||||
{''.join(rows) or '<tr><td colspan=6 style="color:#8b949e">还没有设备上线</td></tr>'}
|
||||
</table>
|
||||
<div class=foot>数据来自 /v1/health · 只显示配对码与流量,看不到任何传输内容</div>'''
|
||||
|
||||
TABLE_NEW = '''<div class=bar>
|
||||
<button class=del id=delAll>删除全部设备</button>
|
||||
<span class=tip>删除会连配对码一起清掉,那台设备下次可以重新设码</span>
|
||||
</div>
|
||||
<table><tr><th>设备</th><th>配对码</th><th>会话</th><th>空闲</th>
|
||||
<th>待发(表/机)</th><th>流量(入/出)</th><th>操作</th></tr>
|
||||
{''.join(rows) or '<tr><td colspan=7 style="color:#8b949e">还没有设备上线</td></tr>'}
|
||||
</table>
|
||||
<script>
|
||||
async function del(deviceId, name, code) {{
|
||||
if (!confirm('删除设备「' + name + '」(配对码 ' + code + ')?\\n\\n'
|
||||
+ '这会:\\n 1. 断开它现在的手表连接\\n'
|
||||
+ ' 2. 从服务器删掉这台设备\\n'
|
||||
+ ' 3. 清掉它的配对码绑定')) return;
|
||||
const r = await fetch('/v1/admin/delete', {{
|
||||
method: 'POST',
|
||||
headers: {{'Content-Type': 'application/json'}},
|
||||
body: JSON.stringify({{deviceId: deviceId}})
|
||||
}});
|
||||
const j = await r.json();
|
||||
if (j.ok) {{
|
||||
alert('已删除「' + (j.name || name) + '」\\n'
|
||||
+ '踢掉会话 ' + j.kicked + ' 个,清掉配对码 ' + (j.codesCleared || []).length + ' 条');
|
||||
location.reload();
|
||||
}} else {{
|
||||
alert('删除失败:' + (j.error || '未知错误'));
|
||||
}}
|
||||
}}
|
||||
document.querySelectorAll('button.del[data-device]').forEach(b => {{
|
||||
b.onclick = () => del(b.dataset.device, b.dataset.name, b.dataset.code);
|
||||
}});
|
||||
const all = document.getElementById('delAll');
|
||||
if (all) all.onclick = async () => {{
|
||||
if (!confirm('删除**全部**设备(连同所有配对码)?\\n\\n清场用,删完所有电脑都要重新设码。'))
|
||||
return;
|
||||
const r = await fetch('/v1/admin/delete_all', {{method: 'POST'}});
|
||||
const j = await r.json();
|
||||
alert('已删除 ' + (j.deleted || 0) + ' 台设备');
|
||||
location.reload();
|
||||
}};
|
||||
</script>
|
||||
<div class=foot>数据来自 /v1/health · 只显示配对码与流量,看不到任何传输内容</div>'''
|
||||
|
||||
# 样式
|
||||
CSS_OLD = ''' .foot{{color:#6e7681;font-size:12px;margin-top:16px}}'''
|
||||
CSS_NEW = ''' .foot{{color:#6e7681;font-size:12px;margin-top:16px}}
|
||||
.bar{{margin-bottom:10px;display:flex;align-items:center;gap:10px;flex-wrap:wrap}}
|
||||
.tip{{color:#6e7681;font-size:12px}}
|
||||
button.del{{background:#3d1418;color:#ff7b72;border:1px solid #6e2b2b;
|
||||
border-radius:6px;padding:4px 12px;font-size:12px;cursor:pointer;
|
||||
font-family:inherit}}
|
||||
button.del:hover{{background:#5a1c22;border-color:#a33;color:#ffa198}}'''
|
||||
|
||||
|
||||
def patch(pairs, label: str) -> bool:
|
||||
text = RELAY.read_text(encoding="utf-8")
|
||||
ok = True
|
||||
for old, new, tag in pairs:
|
||||
if old not in text:
|
||||
print(f" [{label}] [跳过] {tag} —— 锚点没找到")
|
||||
ok = False
|
||||
continue
|
||||
text = text.replace(old, new, 1)
|
||||
print(f" [{label}] {tag}")
|
||||
RELAY.write_text(text, encoding="utf-8", newline="\n")
|
||||
return ok
|
||||
|
||||
|
||||
def main() -> int:
|
||||
text = RELAY.read_text(encoding="utf-8")
|
||||
if "def delete_device" in text:
|
||||
print(" 已经加过删除设备")
|
||||
return 0
|
||||
|
||||
ok = patch([
|
||||
(DELETE_ANCHOR, DELETE_NEW, "Relay.delete_device"),
|
||||
(API_ANCHOR, API_NEW, "管理接口 /delete 和 /delete_all"),
|
||||
(CSS_OLD, CSS_NEW, "删除按钮样式"),
|
||||
(ROW_OLD, ROW_NEW, "设备行加删除按钮"),
|
||||
(TABLE_OLD, TABLE_NEW, "工具栏 + 脚本"),
|
||||
], "中转")
|
||||
|
||||
import ast
|
||||
try:
|
||||
ast.parse(RELAY.read_text(encoding="utf-8"))
|
||||
print(" 语法 OK")
|
||||
except SyntaxError as exc:
|
||||
print(f" 语法错误: 行 {exc.lineno}: {exc.msg}")
|
||||
ok = False
|
||||
return 0 if ok else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user