Update server.js via upload script - 2026-08-01 17:07:56
This commit is contained in:
parent
907020e12e
commit
c656d3bf2a
42
server.js
42
server.js
|
|
@ -178,10 +178,10 @@ function httpStatusCheck(line, timeoutMs = 8000) {
|
|||
}, (res) => {
|
||||
res.resume();
|
||||
const badGateway = [520, 521, 522, 523, 524].includes(res.statusCode);
|
||||
resolve(!badGateway);
|
||||
resolve({ ok: !badGateway, detail: `HTTP ${res.statusCode}` });
|
||||
});
|
||||
req.on('timeout', () => { req.destroy(); resolve(false); });
|
||||
req.on('error', () => resolve(false));
|
||||
req.on('timeout', () => { req.destroy(); resolve({ ok: false, detail: 'HTTP请求超时' }); });
|
||||
req.on('error', (err) => resolve({ ok: false, detail: `HTTP错误:${err.code || err.message}` }));
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
|
@ -189,11 +189,11 @@ function wsHandshakeCheck(line, timeoutMs = 8000) {
|
|||
return new Promise((resolve) => {
|
||||
let done = false;
|
||||
let ws;
|
||||
const finish = (ok) => {
|
||||
const finish = (ok, detail) => {
|
||||
if (done) return;
|
||||
done = true;
|
||||
try { ws && ws.terminate(); } catch (e) {}
|
||||
resolve(ok);
|
||||
resolve({ ok, detail });
|
||||
};
|
||||
try {
|
||||
const port = Number(line.port) || 443;
|
||||
|
|
@ -203,25 +203,31 @@ function wsHandshakeCheck(line, timeoutMs = 8000) {
|
|||
headers: { Host: routeName },
|
||||
servername: line.sni || routeName, // TLS SNI
|
||||
});
|
||||
ws.on('open', () => finish(true));
|
||||
ws.on('unexpected-response', () => finish(false));
|
||||
ws.on('error', () => finish(false));
|
||||
ws.on('open', () => finish(true, 'WS握手成功'));
|
||||
ws.on('unexpected-response', (req2, res2) => finish(false, `WS握手被拒绝:HTTP ${res2 && res2.statusCode}`));
|
||||
ws.on('error', (err) => finish(false, `WS错误:${err.code || err.message}`));
|
||||
} catch (e) {
|
||||
finish(false);
|
||||
finish(false, `WS异常:${e.message}`);
|
||||
}
|
||||
setTimeout(() => finish(false), timeoutMs + 500);
|
||||
setTimeout(() => finish(false, 'WS握手超时'), timeoutMs + 500);
|
||||
});
|
||||
}
|
||||
|
||||
// 返回 { ok, detail } —— detail只在vless-cdn时有意义(http/ws两段各自的失败原因),
|
||||
// 方便"立即检测"排查究竟是端口/Host/SNI哪一环出的问题,而不是只有一个"异常"看不出所以然。
|
||||
async function checkLineConnectivity(line) {
|
||||
if (line.protocol === 'vless-cdn') {
|
||||
const [httpOk, wsOk] = await Promise.all([
|
||||
const [httpResult, wsResult] = await Promise.all([
|
||||
httpStatusCheck(line),
|
||||
wsHandshakeCheck(line),
|
||||
]);
|
||||
return httpOk && wsOk;
|
||||
return {
|
||||
ok: httpResult.ok && wsResult.ok,
|
||||
detail: `HTTP探测: ${httpResult.detail} | WS握手: ${wsResult.detail}`,
|
||||
};
|
||||
}
|
||||
return tcpCheck(line.addr, line.port);
|
||||
const tcpOk = await tcpCheck(line.addr, line.port);
|
||||
return { ok: tcpOk, detail: tcpOk ? 'TCP连通' : 'TCP连接失败/超时' };
|
||||
}
|
||||
|
||||
// 后台定时巡检:每 JMS_CHECK_INTERVAL_MS 跑一轮,只在状态发生变化(正常↔异常)时才发Telegram,
|
||||
|
|
@ -237,12 +243,12 @@ async function runJmsMonitorCycle() {
|
|||
|
||||
for (const line of lines) {
|
||||
try {
|
||||
const ok = await checkLineConnectivity(line);
|
||||
const { ok, detail } = await checkLineConnectivity(line);
|
||||
const newStatus = ok ? 'normal' : 'abnormal';
|
||||
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
||||
const name = line.name || line.addr;
|
||||
const msg = newStatus === 'abnormal'
|
||||
? `⚠️ <b>${name}</b> 检测异常,无法连接\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`
|
||||
? `⚠️ <b>${name}</b> 检测异常,无法连接\n协议:${line.protocol}\n地址:${line.addr}:${line.port}\n详情:${detail}`
|
||||
: `✅ <b>${name}</b> 已恢复正常\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`;
|
||||
sendTelegramMessage(msg).catch(() => {}); // Telegram没配置/发送失败都不影响检测本身
|
||||
}
|
||||
|
|
@ -568,16 +574,16 @@ app.post('/api/jms/check-line', requireAuth, jmsCheckLimiter, async (req, res) =
|
|||
const line = req.body && req.body.line;
|
||||
if (!line || !line.addr) return res.status(400).json({ error: '线路信息不完整' });
|
||||
try {
|
||||
const ok = await checkLineConnectivity(line);
|
||||
const { ok, detail } = await checkLineConnectivity(line);
|
||||
const newStatus = ok ? 'normal' : 'abnormal';
|
||||
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
||||
const name = line.name || line.addr;
|
||||
const msg = newStatus === 'abnormal'
|
||||
? `⚠️ <b>${name}</b> 检测异常,无法连接\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`
|
||||
? `⚠️ <b>${name}</b> 检测异常,无法连接\n协议:${line.protocol}\n地址:${line.addr}:${line.port}\n详情:${detail}`
|
||||
: `✅ <b>${name}</b> 已恢复正常\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`;
|
||||
sendTelegramMessage(msg).catch(() => {});
|
||||
}
|
||||
res.json({ ok: true, status: newStatus, checkedAt: Date.now() });
|
||||
res.json({ ok: true, status: newStatus, detail, checkedAt: Date.now() });
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: e.message });
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue