Split gateway control and dataplane into separate services
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
import fs from 'node:fs';
|
||||
import http from 'node:http';
|
||||
import path from 'node:path';
|
||||
import { settings } from './config.js';
|
||||
import { createSingboxRuntime } from './singboxRuntime.js';
|
||||
|
||||
const socketPath = settings.dataplaneSocket;
|
||||
const runtime = createSingboxRuntime({
|
||||
configPath: settings.configPath,
|
||||
gateway: true,
|
||||
tproxyChain: settings.tproxyChain,
|
||||
});
|
||||
let ready = false;
|
||||
|
||||
function sendJson(res, statusCode, payload) {
|
||||
res.writeHead(statusCode, { 'content-type': 'application/json; charset=utf-8' });
|
||||
res.end(JSON.stringify(payload));
|
||||
}
|
||||
|
||||
const server = http.createServer(async (req, res) => {
|
||||
try {
|
||||
if (req.method === 'GET' && req.url === '/status') {
|
||||
return sendJson(res, ready ? 200 : 503, {
|
||||
...await runtime.refresh(),
|
||||
ready,
|
||||
});
|
||||
}
|
||||
if (req.method === 'POST' && req.url === '/apply') {
|
||||
return sendJson(res, 200, await runtime.apply());
|
||||
}
|
||||
if (req.method === 'POST' && req.url === '/restart') {
|
||||
return sendJson(res, 200, await runtime.restart());
|
||||
}
|
||||
if (req.method === 'POST' && req.url === '/stop') {
|
||||
return sendJson(res, 200, await runtime.stop());
|
||||
}
|
||||
return sendJson(res, 404, { error: 'Не найдено' });
|
||||
} catch (error) {
|
||||
return sendJson(res, 500, { error: error.message || String(error) });
|
||||
}
|
||||
});
|
||||
|
||||
fs.mkdirSync(path.dirname(socketPath), { recursive: true });
|
||||
fs.rmSync(socketPath, { force: true });
|
||||
server.listen(socketPath, async () => {
|
||||
fs.chmodSync(socketPath, 0o660);
|
||||
try {
|
||||
await runtime.apply();
|
||||
} catch (error) {
|
||||
console.warn(`[dataplane] sing-box не запущен: ${error.message}`);
|
||||
} finally {
|
||||
ready = true;
|
||||
console.log(`[dataplane] control socket: ${socketPath}`);
|
||||
}
|
||||
});
|
||||
|
||||
let shuttingDown = false;
|
||||
async function shutdown() {
|
||||
if (shuttingDown) return;
|
||||
shuttingDown = true;
|
||||
ready = false;
|
||||
await runtime.shutdown();
|
||||
server.close(() => {
|
||||
fs.rmSync(socketPath, { force: true });
|
||||
process.exit(0);
|
||||
});
|
||||
}
|
||||
|
||||
process.on('SIGTERM', shutdown);
|
||||
process.on('SIGINT', shutdown);
|
||||
Reference in New Issue
Block a user