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) => {
|
||||||
res.resume();
|
res.resume();
|
||||||
const badGateway = [520, 521, 522, 523, 524].includes(res.statusCode);
|
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('timeout', () => { req.destroy(); resolve({ ok: false, detail: 'HTTP请求超时' }); });
|
||||||
req.on('error', () => resolve(false));
|
req.on('error', (err) => resolve({ ok: false, detail: `HTTP错误:${err.code || err.message}` }));
|
||||||
req.end();
|
req.end();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -189,11 +189,11 @@ function wsHandshakeCheck(line, timeoutMs = 8000) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
let done = false;
|
let done = false;
|
||||||
let ws;
|
let ws;
|
||||||
const finish = (ok) => {
|
const finish = (ok, detail) => {
|
||||||
if (done) return;
|
if (done) return;
|
||||||
done = true;
|
done = true;
|
||||||
try { ws && ws.terminate(); } catch (e) {}
|
try { ws && ws.terminate(); } catch (e) {}
|
||||||
resolve(ok);
|
resolve({ ok, detail });
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const port = Number(line.port) || 443;
|
const port = Number(line.port) || 443;
|
||||||
|
|
@ -203,25 +203,31 @@ function wsHandshakeCheck(line, timeoutMs = 8000) {
|
||||||
headers: { Host: routeName },
|
headers: { Host: routeName },
|
||||||
servername: line.sni || routeName, // TLS SNI
|
servername: line.sni || routeName, // TLS SNI
|
||||||
});
|
});
|
||||||
ws.on('open', () => finish(true));
|
ws.on('open', () => finish(true, 'WS握手成功'));
|
||||||
ws.on('unexpected-response', () => finish(false));
|
ws.on('unexpected-response', (req2, res2) => finish(false, `WS握手被拒绝:HTTP ${res2 && res2.statusCode}`));
|
||||||
ws.on('error', () => finish(false));
|
ws.on('error', (err) => finish(false, `WS错误:${err.code || err.message}`));
|
||||||
} catch (e) {
|
} 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) {
|
async function checkLineConnectivity(line) {
|
||||||
if (line.protocol === 'vless-cdn') {
|
if (line.protocol === 'vless-cdn') {
|
||||||
const [httpOk, wsOk] = await Promise.all([
|
const [httpResult, wsResult] = await Promise.all([
|
||||||
httpStatusCheck(line),
|
httpStatusCheck(line),
|
||||||
wsHandshakeCheck(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,
|
// 后台定时巡检:每 JMS_CHECK_INTERVAL_MS 跑一轮,只在状态发生变化(正常↔异常)时才发Telegram,
|
||||||
|
|
@ -237,12 +243,12 @@ async function runJmsMonitorCycle() {
|
||||||
|
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
try {
|
try {
|
||||||
const ok = await checkLineConnectivity(line);
|
const { ok, detail } = await checkLineConnectivity(line);
|
||||||
const newStatus = ok ? 'normal' : 'abnormal';
|
const newStatus = ok ? 'normal' : 'abnormal';
|
||||||
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
||||||
const name = line.name || line.addr;
|
const name = line.name || line.addr;
|
||||||
const msg = newStatus === 'abnormal'
|
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}`;
|
: `✅ <b>${name}</b> 已恢复正常\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`;
|
||||||
sendTelegramMessage(msg).catch(() => {}); // Telegram没配置/发送失败都不影响检测本身
|
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;
|
const line = req.body && req.body.line;
|
||||||
if (!line || !line.addr) return res.status(400).json({ error: '线路信息不完整' });
|
if (!line || !line.addr) return res.status(400).json({ error: '线路信息不完整' });
|
||||||
try {
|
try {
|
||||||
const ok = await checkLineConnectivity(line);
|
const { ok, detail } = await checkLineConnectivity(line);
|
||||||
const newStatus = ok ? 'normal' : 'abnormal';
|
const newStatus = ok ? 'normal' : 'abnormal';
|
||||||
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
if (line.monitorStatus && line.monitorStatus !== newStatus) {
|
||||||
const name = line.name || line.addr;
|
const name = line.name || line.addr;
|
||||||
const msg = newStatus === 'abnormal'
|
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}`;
|
: `✅ <b>${name}</b> 已恢复正常\n协议:${line.protocol}\n地址:${line.addr}:${line.port}`;
|
||||||
sendTelegramMessage(msg).catch(() => {});
|
sendTelegramMessage(msg).catch(() => {});
|
||||||
}
|
}
|
||||||
res.json({ ok: true, status: newStatus, checkedAt: Date.now() });
|
res.json({ ok: true, status: newStatus, detail, checkedAt: Date.now() });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
res.status(500).json({ error: e.message });
|
res.status(500).json({ error: e.message });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue