返回提交历史
Modified
src/controllers/custom/configController.ts
+2
-0
Modified
src/services/webService.ts
+26
-0
Modified
static/webui/script.js
+8
-4
XFEstudio/SpaceNinjaServer
chore(webui): keep config in sync with multiple tabs (#2325)
Adding "wsid" to uniquely identify a given tab (by the websocket connection) so we can avoid needless refreshing on the same tab. Closes #2316 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2325 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
abb5b888
代码差异
3 个文件
+36
-4
@@ -2,6 +2,7 @@ import { RequestHandler } from "express";
2
2
import { config } from "@/src/services/configService";
3
3
import { getAccountForRequest, isAdministrator } from "@/src/services/loginService";
4
4
import { saveConfig } from "@/src/services/configWatcherService";
5
import { sendWsBroadcastExcept } from "@/src/services/webService";
5
6
6
7
export const getConfigController: RequestHandler = async (req, res) => {
7
8
const account = await getAccountForRequest(req);
@@ -24,6 +25,7 @@ export const setConfigController: RequestHandler = async (req, res) => {
24
25
const [obj, idx] = configIdToIndexable(id);
25
26
obj[idx] = value;
26
27
}
28
sendWsBroadcastExcept(parseInt(String(req.query.wsid)), { config_reloaded: true });
27
29
await saveConfig();
28
30
res.end();
29
31
} else {
@@ -136,7 +136,10 @@ export const stopWebServer = async (): Promise<void> => {
136
136
await Promise.all(promises);
137
137
};
138
138
139
let lastWsid: number = 0;
140
139
141
interface IWsCustomData extends ws {
142
id?: number;
140
143
accountId?: string;
141
144
}
142
145
@@ -150,6 +153,7 @@ interface IWsMsgFromClient {
150
153
}
151
154
152
155
interface IWsMsgToClient {
156
//wsid?: number;
153
157
reload?: boolean;
154
158
ports?: {
155
159
http: number | undefined;
@@ -174,6 +178,10 @@ const wsOnConnect = (ws: ws, req: http.IncomingMessage): void => {
174
178
ws.close();
175
179
return;
176
180
}
181
182
(ws as IWsCustomData).id = ++lastWsid;
183
ws.send(JSON.stringify({ wsid: lastWsid }));
184
177
185
// eslint-disable-next-line @typescript-eslint/no-misused-promises
178
186
ws.on("message", async msg => {
179
187
const data = JSON.parse(String(msg)) as IWsMsgFromClient;
@@ -268,3 +276,21 @@ export const sendWsBroadcastTo = (accountId: string, data: IWsMsgToClient): void
268
276
}
269
277
}
270
278
};
279
280
export const sendWsBroadcastExcept = (wsid: number | undefined, data: IWsMsgToClient): void => {
281
const msg = JSON.stringify(data);
282
if (wsServer) {
283
for (const client of wsServer.clients) {
284
if ((client as IWsCustomData).id != wsid) {
285
client.send(msg);
286
}
287
}
288
}
289
if (wssServer) {
290
for (const client of wssServer.clients) {
291
if ((client as IWsCustomData).id != wsid) {
292
client.send(msg);
293
}
294
}
295
}
296
};
@@ -10,7 +10,8 @@
10
10
11
11
let auth_pending = false,
12
12
did_initial_auth = false,
13
ws_is_open = false;
13
ws_is_open = false,
14
wsid = 0;
14
15
const sendAuth = isRegister => {
15
16
if (ws_is_open && localStorage.getItem("email") && localStorage.getItem("password")) {
16
17
auth_pending = true;
@@ -34,6 +35,9 @@ function openWebSocket() {
34
35
};
35
36
window.ws.onmessage = e => {
36
37
const msg = JSON.parse(e.data);
38
if ("wsid" in msg) {
39
wsid = msg.wsid;
40
}
37
41
if ("reload" in msg) {
38
42
setTimeout(() => {
39
43
getWebSocket().then(() => {
@@ -1858,7 +1862,7 @@ for (const id of uiConfigs) {
1858
1862
value = parseInt(value);
1859
1863
}
1860
1864
$.post({
1861
url: "/custom/setConfig?" + window.authz,
1865
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
1862
1866
contentType: "application/json",
1863
1867
data: JSON.stringify({ [id]: value })
1864
1868
});
@@ -1866,7 +1870,7 @@ for (const id of uiConfigs) {
1866
1870
} else if (elm.type == "checkbox") {
1867
1871
elm.onchange = function () {
1868
1872
$.post({
1869
url: "/custom/setConfig?" + window.authz,
1873
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
1870
1874
contentType: "application/json",
1871
1875
data: JSON.stringify({ [id]: this.checked })
1872
1876
}).then(() => {
@@ -1881,7 +1885,7 @@ for (const id of uiConfigs) {
1881
1885
function doSaveConfig(id) {
1882
1886
const elm = document.getElementById(id);
1883
1887
$.post({
1884
url: "/custom/setConfig?" + window.authz,
1888
url: "/custom/setConfig?" + window.authz + "&wsid=" + wsid,
1885
1889
contentType: "application/json",
1886
1890
data: JSON.stringify({ [id]: parseInt(elm.value) })
1887
1891
});