docs: 项目文档、设计图、工具、协议模块、部署说明
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env node
|
||||
// 连接诊断: TCP / WS 分段计时, 零依赖, Node >= 22 (内置 WebSocket)
|
||||
// 用法: node tools/diag-connection.mjs ws://192.168.1.5:3001 [次数]
|
||||
// 说明: WS 模式下服务端需对 {"type":"ping"} 回应任意消息(建议 {"type":"pong"})
|
||||
import net from "node:net";
|
||||
|
||||
const url = process.argv[2];
|
||||
const times = Number(process.argv[3] || 5);
|
||||
if (!url) {
|
||||
console.error("用法: node tools/diag-connection.mjs <ws://host:port | http://host:port> [次数]");
|
||||
process.exit(1);
|
||||
}
|
||||
const u = new URL(url);
|
||||
const host = u.hostname;
|
||||
const port = Number(u.port || (u.protocol === "wss:" || u.protocol === "https:" ? 443 : 80));
|
||||
const isWs = u.protocol === "ws:" || u.protocol === "wss:";
|
||||
const tcpMs = [], openMs = [], rttMs = [];
|
||||
|
||||
for (let i = 0; i < times; i++) {
|
||||
const t0 = performance.now();
|
||||
try {
|
||||
await new Promise((res, rej) => {
|
||||
const s = net.connect({ host, port });
|
||||
const to = setTimeout(() => { s.destroy(); rej(new Error("TCP timeout")); }, 3000);
|
||||
s.once("connect", () => { clearTimeout(to); tcpMs.push(performance.now() - t0); s.destroy(); res(); });
|
||||
s.once("error", (e) => { clearTimeout(to); rej(e); });
|
||||
});
|
||||
} catch (err) { tcpMs.push(-1); console.warn("第" + (i+1) + "次 TCP 失败: " + err.message); }
|
||||
if (!isWs) continue;
|
||||
const t1 = performance.now();
|
||||
try {
|
||||
const ws = new WebSocket(url);
|
||||
await new Promise((res, rej) => { ws.onopen = res; ws.onerror = () => rej(new Error("WS open 失败")); });
|
||||
openMs.push(performance.now() - t1);
|
||||
const t2 = performance.now();
|
||||
ws.send(JSON.stringify({ type: "ping", t: Date.now() }));
|
||||
await new Promise((res) => {
|
||||
const to = setTimeout(() => { rttMs.push(-1); res(); }, 3000);
|
||||
ws.onmessage = () => { clearTimeout(to); rttMs.push(performance.now() - t2); res(); };
|
||||
});
|
||||
ws.close();
|
||||
} catch (err) { openMs.push(-1); console.warn("第" + (i+1) + "次 WS 失败: " + err.message); }
|
||||
}
|
||||
|
||||
const stat = (a) => {
|
||||
const v = a.filter((x) => x >= 0);
|
||||
if (!v.length) return "全部失败";
|
||||
const avg = v.reduce((s, x) => s + x, 0) / v.length;
|
||||
return "avg=" + avg.toFixed(1) + "ms min=" + Math.min(...v).toFixed(1) + "ms max=" + Math.max(...v).toFixed(1) + "ms";
|
||||
};
|
||||
console.log("目标: " + url + " (" + host + ":" + port + ") x" + times);
|
||||
console.log("TCP连接 : " + stat(tcpMs) + " <- >20ms 查防火墙/IPv6/代理");
|
||||
if (isWs) {
|
||||
console.log("WS握手 : " + stat(openMs) + " <- >50ms 查服务端WS框架/鉴权");
|
||||
console.log("消息RTT : " + stat(rttMs) + " <- >50ms 查串行往返/服务端处理");
|
||||
}
|
||||
Reference in New Issue
Block a user