feat: 소켓으로 마인크래프트 서버 상태 실시간 감지
- 백엔드: 3초마다 서버 상태 확인, 변경 시 브로드캐스트 - 프론트엔드: minecraft_servers 이벤트로 UI 자동 업데이트 - 외부에서 서버 시작/종료해도 UI에 반영
This commit is contained in:
parent
2a62dc6739
commit
fe86d02a72
3 changed files with 51 additions and 1 deletions
|
|
@ -1346,4 +1346,6 @@ router.get("/servers/status/:serverPath(*)", async (req, res) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 서버 상태 함수들 export (소켓 브로드캐스트용)
|
||||||
|
export { getServerList, getRunningServer, getContainerStatus };
|
||||||
export default router;
|
export default router;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,11 @@ import {
|
||||||
import apiRoutes from "./routes/api.js";
|
import apiRoutes from "./routes/api.js";
|
||||||
import authRoutes from "./routes/auth.js";
|
import authRoutes from "./routes/auth.js";
|
||||||
import linkRoutes from "./routes/link.js";
|
import linkRoutes from "./routes/link.js";
|
||||||
import adminRoutes from "./routes/admin.js";
|
import adminRoutes, {
|
||||||
|
getServerList,
|
||||||
|
getRunningServer,
|
||||||
|
getContainerStatus,
|
||||||
|
} from "./routes/admin.js";
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = path.dirname(__filename);
|
const __dirname = path.dirname(__filename);
|
||||||
|
|
@ -153,11 +157,48 @@ async function refreshLogs() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 마인크래프트 서버 상태 캐시 (변경 감지용)
|
||||||
|
let lastServerStatusHash = "";
|
||||||
|
|
||||||
|
// 마인크래프트 서버 상태 갱신 및 브로드캐스트
|
||||||
|
async function refreshServerStatus() {
|
||||||
|
try {
|
||||||
|
const servers = await getServerList();
|
||||||
|
const runningContainer = await getRunningServer();
|
||||||
|
|
||||||
|
// 각 서버의 상태 확인
|
||||||
|
const serversWithStatus = await Promise.all(
|
||||||
|
servers.map(async (server) => {
|
||||||
|
const status = await getContainerStatus(server.path);
|
||||||
|
return {
|
||||||
|
...server,
|
||||||
|
running: status === "running",
|
||||||
|
status,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
// 상태 변경 감지 (해시 비교)
|
||||||
|
const currentHash = JSON.stringify({ serversWithStatus, runningContainer });
|
||||||
|
if (currentHash !== lastServerStatusHash) {
|
||||||
|
lastServerStatusHash = currentHash;
|
||||||
|
io.emit("minecraft_servers", {
|
||||||
|
servers: serversWithStatus,
|
||||||
|
runningContainer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// 오류 무시 (서버 디렉토리가 없을 수 있음)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 1초마다 데이터 갱신
|
// 1초마다 데이터 갱신
|
||||||
setInterval(refreshAndBroadcast, 1000);
|
setInterval(refreshAndBroadcast, 1000);
|
||||||
setInterval(refreshLogs, 1000);
|
setInterval(refreshLogs, 1000);
|
||||||
|
setInterval(refreshServerStatus, 3000); // 서버 상태는 3초마다
|
||||||
refreshAndBroadcast();
|
refreshAndBroadcast();
|
||||||
refreshLogs();
|
refreshLogs();
|
||||||
|
refreshServerStatus();
|
||||||
|
|
||||||
// SPA 라우팅 - 모든 경로에 대해 index.html 제공
|
// SPA 라우팅 - 모든 경로에 대해 index.html 제공
|
||||||
app.get("*", (req, res) => {
|
app.get("*", (req, res) => {
|
||||||
|
|
|
||||||
|
|
@ -1272,6 +1272,13 @@ export default function Admin({ isMobile = false }) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 마인크래프트 서버 상태 실시간 업데이트
|
||||||
|
socket.on("minecraft_servers", (data) => {
|
||||||
|
if (data?.servers) {
|
||||||
|
setServers(data.servers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 월드 정보 요청
|
// 월드 정보 요청
|
||||||
socket.emit("get_worlds");
|
socket.emit("get_worlds");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue