feat(webui): global chat websocket client
This commit is contained in:
parent
47e497867f
commit
33dab85c1c
60
webui/src/lib/chat.svelte.js
Normal file
60
webui/src/lib/chat.svelte.js
Normal file
@ -0,0 +1,60 @@
|
||||
import { clientId } from "./api.js";
|
||||
|
||||
class ChatClient {
|
||||
connected = $state(false);
|
||||
turn = $state(null); // 最新 turn 快照(任意 session),供活动脊
|
||||
#socket = null;
|
||||
#handlers = new Set();
|
||||
#reconnectTimer = null;
|
||||
#stopped = false;
|
||||
|
||||
connect() {
|
||||
if (this.#socket) return;
|
||||
this.#stopped = false;
|
||||
const scheme = location.protocol === "https:" ? "wss" : "ws";
|
||||
const ws = new WebSocket(`${scheme}://${location.host}/ws?client_id=${encodeURIComponent(clientId())}`);
|
||||
this.#socket = ws;
|
||||
ws.onopen = () => {
|
||||
this.connected = true;
|
||||
this.#dispatch({ type: "_open" });
|
||||
};
|
||||
ws.onerror = () => ws.close();
|
||||
ws.onclose = () => {
|
||||
this.connected = false;
|
||||
this.#socket = null;
|
||||
this.#dispatch({ type: "_close" });
|
||||
if (!this.#stopped) this.#reconnectTimer = setTimeout(() => this.connect(), 1800);
|
||||
};
|
||||
ws.onmessage = (event) => {
|
||||
const frame = JSON.parse(event.data);
|
||||
if (frame.type === "turn_updated" && frame.snapshot) this.turn = frame.snapshot;
|
||||
this.#dispatch(frame);
|
||||
};
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
this.#stopped = true;
|
||||
clearTimeout(this.#reconnectTimer);
|
||||
this.#socket?.close();
|
||||
this.#socket = null;
|
||||
}
|
||||
|
||||
send(frame) {
|
||||
if (this.#socket?.readyState === WebSocket.OPEN) {
|
||||
this.#socket.send(JSON.stringify(frame));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
subscribe(handler) {
|
||||
this.#handlers.add(handler);
|
||||
return () => this.#handlers.delete(handler);
|
||||
}
|
||||
|
||||
#dispatch(frame) {
|
||||
for (const handler of this.#handlers) handler(frame);
|
||||
}
|
||||
}
|
||||
|
||||
export const chat = new ChatClient();
|
||||
Loading…
x
Reference in New Issue
Block a user