-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
174 lines (147 loc) · 6.02 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
// =============================================================
// 依賴設定
// =============================================================
const http = require("http");
const { URL } = require("url");
const WebSocket = require("ws");
const fs = require("fs");
const path = require("path");
// =============================================================
// 維護模式設定
// =============================================================
let maintenanceMode = false; // 初始狀態為非維護模式
// =============================================================
// Controller
// =============================================================
const SystemInfoController = require("./controllers/SystemInfoController");
const _systemInfoController = new SystemInfoController();
const DownloadController = require("./controllers/DownloadController");
const _downloadController = new DownloadController();
const LogController = require("./controllers/LogController");
const _logController = new LogController();
const DBController = require("./controllers/DBController");
const MetricsController = require("./controllers/MetricsController");
// =============================================================
// HTTP 路由處理函式
// =============================================================
async function parseRequestBody(request) {
return new Promise((resolve) => {
let body = '';
request.on("data", (chunk) => { body += chunk.toString(); });
request.on("end", () => resolve(JSON.parse(body)));
});
}
async function parseRequestBody(request) {
return new Promise((resolve) => {
let body = '';
request.on("data", (chunk) => { body += chunk.toString(); });
request.on("end", () => resolve(JSON.parse(body)));
});
}
async function handleHttpRequest(request, response) {
const start = Date.now();
const { pathname } = new URL(request.url, `http://${request.headers.host}`);
const method = request.method;
let statusCode = 200;
// 檢查維護模式
if (maintenanceMode && pathname !== "/system") {
statusCode = 503;
MetricsController.countRequest(method, pathname, statusCode);
response.writeHead(503, { "Content-Type": "text/plain" }).end("Service is under maintenance. Please try again later.");
return;
}
// 服務 DatabaseOperations.html
if (pathname === "/db-operations" && method === "GET") {
fs.readFile(path.join(__dirname, "views/DatabaseOperations.html"), "utf-8", (err, data) => {
if (err) {
response.writeHead(500, { "Content-Type": "text/plain" }).end("Error loading DatabaseOperations view");
return;
}
response.writeHead(200, { "Content-Type": "text/html" }).end(data);
});
return;
}
// CRUD API
if (pathname === "/db/execute-query" && method === "POST") {
const { query } = await parseRequestBody(request);
try {
const result = await DBController.executeQuery(query);
response.writeHead(200, { "Content-Type": "application/json" }).end(JSON.stringify(result.recordset || []));
} catch (error) {
response.writeHead(500, { "Content-Type": "application/json" }).end(JSON.stringify({ error: "Failed to execute query" }));
}
return;
}
// 增加 `/metrics` 路徑供 Prometheus 獲取數據
if (pathname === "/metrics" && request.method === "GET") {
await MetricsController.getMetrics(request, response);
return; // 確保請求在這裡結束
}
// 系統資訊和下載處理
if (pathname === "/system" && request.method === "GET") {
_systemInfoController.getSystemInfo(request, response);
return;
} else if (pathname === "/download" && request.method === "GET") {
_downloadController.handleFileDownload(request, response);
return;
}
// 無法匹配的路徑
statusCode = 404;
MetricsController.countRequest(method, pathname, statusCode);
response.writeHead(404, { "Content-Type": "text/plain" }).end("Not Found");
// 計算請求的處理時間並更新指標
const duration = (Date.now() - start) / 1000;
MetricsController.countRequest(method, pathname, statusCode);
MetricsController.observeRequestDuration(method, pathname, statusCode, duration);
}
// =============================================================
// 啟動 HTTP 伺服器
// =============================================================
function createHttpServer() {
const httpServer = http.createServer(handleHttpRequest);
httpServer.listen(3001, () => {
console.log("HTTP server running on http://localhost:3001");
});
}
// =============================================================
// 建立 WebSocket 伺服器
// =============================================================
function createWebSocketServer() {
const wsServer = new WebSocket.Server({ port: 3002 });
wsServer.on("connection", handleWebSocketConnection);
console.log("WebSocket server running on ws://localhost:3002");
return wsServer;
}
// =============================================================
// 處理 WebSocket 連線
// =============================================================
function handleWebSocketConnection(ws) {
let statusCode = 300;
// 檢查維護模式
if (maintenanceMode) {
ws.send("Service is under maintenance. WebSocket connection will be closed.");
ws.close();
return;
}
console.log("WebSocket client connected");
MetricsController.incrementWebSocketConnections();
MetricsController.countRequest("WebSocket", "/ws/connect", statusCode);
ws.on("message", (message) => {
console.log("Received message:", message.toString());
});
ws.on("close", () => {
console.log("WebSocket client disconnected");
MetricsController.decrementWebSocketConnections();
MetricsController.countRequest("WebSocket", "/ws/disconnect", statusCode);
});
}
// =============================================================
// 啟動 HTTP 和 WebSocket 伺服器
// =============================================================
function startServers() {
createHttpServer();
createWebSocketServer();
}
// 初始化並啟動應用
DBController.initializeDatabase();
startServers();