import { randomUUID } from "crypto"; import Logs from "./logs.js"; /** * 解析推送过来的消息 * @param {*} data * @returns {object} */ const parseMessage = (data) => { let message; try { message = JSON.parse(data); } catch(e) { message = { text: data }; } return message; } class WebSocketClient { #wsClient; constructor(wsClient) { this.#wsClient = wsClient; } on(type, callback) { if (type == 'message') { this.#wsClient.on('message', (event) => { const data = parseMessage(event.data); callback(data); }); } else { this.#wsClient.on(type, callback); } } send(message) { this.#wsClient.send(JSON.stringify(message)); } close() { this.#wsClient.close(); } } class WsClientData { #wsClient; #name; #request = { callbacks: {}, functions: {} }; #response = { functions: {} }; constructor(wsClient, name='wsClient') { this.#wsClient = wsClient.constructor.name === 'WebSocket' ? new WebSocketClient(wsClient) : wsClient; this.#name = name; this.#wsClient.on('message', (message) => { this.#handleMessage(message); }); this.#wsClient.on('error', (error) => { Logs.err('wsClient error', error); }); this.#wsClient.on('close', () => { Logs.outDev('wsClient closed'); }); } get(type, params) { return new Promise((resolve, reject) => { const id = randomUUID(); try { this.#wsClient.send({ method: 'get', type, id, params }); this.#request.callbacks[id] = resolve; } catch (error) { delete this.#request.callbacks[id]; reject(error); } }); } registerResponse(type, func) { this.#response.functions[type] = func; } #responseData(type, params, id) { const func = this.#response.functions[type]; func?.(params).then(data => { this.#wsClient.send({ type: 'response', data, id }); }); } post(type, data) { this.#wsClient.send({ method: 'post', type, data }); } registerRequest(type, func) { this.#request.functions[type] = func; } #requestData(type, data) { const func = this.#request.functions[type]; func?.(data); } #handleMessage(message) { const { callbacks } = this.#request; const { method, type, data, error, id, params } = message; if (error) { console.error(error); } if (method == 'get' && id) { this.#responseData(type, params, id); } else if (type == 'response' && id && callbacks[id]) { callbacks[id](data); delete callbacks[id]; } else if (method == 'post' && type) { this.#requestData(type, data); } } } export default WsClientData;