mirror of
https://github.com/Break27/kvmd.git
synced 2026-02-06 10:26:38 +08:00
websocket solution
This commit is contained in:
parent
c536a1ac49
commit
1da10b3996
@ -20,10 +20,10 @@ class RemoteApi:
|
|||||||
|
|
||||||
# =====
|
# =====
|
||||||
|
|
||||||
@exposed_http("POST", "/remote")
|
@exposed_http("POST", "/remote/update")
|
||||||
async def __state_handler(self, _: Request) -> Response:
|
async def __remote_update_handler(self, _: Request) -> Response:
|
||||||
return make_json_response({
|
return make_json_response({
|
||||||
"hosts": await self.__remote.get_state(),
|
"update": await self.__remote.update(),
|
||||||
})
|
})
|
||||||
|
|
||||||
@exposed_http("POST", "/remote/control")
|
@exposed_http("POST", "/remote/control")
|
||||||
|
|||||||
@ -5,22 +5,45 @@ import { $, $$$, tools } from "../tools.js";
|
|||||||
import { fromNow } from "./relativeTime.js";
|
import { fromNow } from "./relativeTime.js";
|
||||||
|
|
||||||
|
|
||||||
let prev_state = {};
|
|
||||||
|
|
||||||
let loading = false;
|
let loading = false;
|
||||||
|
|
||||||
|
let firstRun = true;
|
||||||
|
|
||||||
/********************************************************/
|
/********************************************************/
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
loadRemoteApi(x => makeView(x));
|
|
||||||
setInterval(update, 10000);
|
|
||||||
|
|
||||||
$("rf").addEventListener("click", refresh);
|
$("rf").addEventListener("click", refresh);
|
||||||
|
createWebSocket();
|
||||||
|
setInterval(updateOfflineTime, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function update() {
|
function createWebSocket() {
|
||||||
loadRemoteApi(x => x.forEach(y => updateState(y)));
|
let address = `wss://${window.location.host}/api/ws`;
|
||||||
updateOfflineTime();
|
let socket = new WebSocket(address);
|
||||||
|
|
||||||
|
socket.onopen = () => {
|
||||||
|
console.log("WebSocket connection established.");
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = (e) => {
|
||||||
|
let { event_type, event } = JSON.parse(e.data);
|
||||||
|
|
||||||
|
if (event_type != "remote_state") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstRun) { makeView(event); firstRun = false; }
|
||||||
|
else event.forEach(x => updateState(x));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onerror = () => {
|
||||||
|
socket.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onclose = () => {
|
||||||
|
console.log("Websocket connection lost. Retrying in 5 seconds.");
|
||||||
|
setTimeout(createWebSocket, 5000);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh(event) {
|
function refresh(event) {
|
||||||
@ -30,8 +53,7 @@ function refresh(event) {
|
|||||||
let icon = $$$("#rf div.icon")[0];
|
let icon = $$$("#rf div.icon")[0];
|
||||||
icon.classList.toggle("spin");
|
icon.classList.toggle("spin");
|
||||||
|
|
||||||
prev_state = {};
|
getApiUpdate(x => {
|
||||||
loadRemoteApi(x => {
|
|
||||||
x.forEach(y => updateState(y));
|
x.forEach(y => updateState(y));
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
icon.classList.toggle("spin")
|
icon.classList.toggle("spin")
|
||||||
@ -59,17 +81,15 @@ function guards(http) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadRemoteApi(callback) {
|
function getApiUpdate(callback) {
|
||||||
let http = tools.makeRequest("POST", "/api/remote", () => {
|
let http = tools.makeRequest("POST", "/api/remote/update", () => {
|
||||||
let response = http.responseText;
|
let response = http.responseText;
|
||||||
|
|
||||||
if (! guards(http)) return;
|
if (! guards(http)) return;
|
||||||
if (! response) return;
|
if (! response) return;
|
||||||
|
|
||||||
let hosts = JSON.parse(response).result.hosts;
|
let update = JSON.parse(response).result.update;
|
||||||
let diff = stateDiff(hosts);
|
callback(update);
|
||||||
|
|
||||||
callback(diff);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,9 +104,7 @@ function actionPerform(target, action) {
|
|||||||
let result = JSON.parse(response).result;
|
let result = JSON.parse(response).result;
|
||||||
|
|
||||||
if (result.code != 0) {
|
if (result.code != 0) {
|
||||||
delete prev_state[target];
|
|
||||||
let state = $$$(`.host[name='${target}'] span.state`)[0];
|
let state = $$$(`.host[name='${target}'] span.state`)[0];
|
||||||
|
|
||||||
state.innerHTML = ' ⦻ Failed';
|
state.innerHTML = ' ⦻ Failed';
|
||||||
setTimeout(update, 3000);
|
setTimeout(update, 3000);
|
||||||
}
|
}
|
||||||
@ -175,18 +193,3 @@ function updateOfflineTime(name) {
|
|||||||
state.innerHTML = ' – ' + fromNow(timestamp);
|
state.innerHTML = ' – ' + fromNow(timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function stateDiff(hosts) {
|
|
||||||
let diff = [];
|
|
||||||
|
|
||||||
for (const host of hosts) {
|
|
||||||
if (! (host.name in prev_state)
|
|
||||||
|| prev_state[host.name].online != host.online)
|
|
||||||
{
|
|
||||||
diff.push(host);
|
|
||||||
}
|
|
||||||
prev_state[host.name] = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
return diff;
|
|
||||||
}
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user