mirror of
https://github.com/fusionpbx/fusionpbx.git
synced 2026-01-06 11:43:50 +00:00
Update dashboard with cpu status websockets (#7400)
* Remove setting hardcoded timer * Use websockets for real-time CPU status on dashboard * Add system_dashboard service file * moved javascript file to core
This commit is contained in:
116
core/dashboard/resources/javascript/ws_client.js
Normal file
116
core/dashboard/resources/javascript/ws_client.js
Normal file
@@ -0,0 +1,116 @@
|
||||
class ws_client {
|
||||
constructor(url, token) {
|
||||
this.ws = new WebSocket(url);
|
||||
this.ws.addEventListener('message', this._onMessage.bind(this));
|
||||
this._nextId = 1;
|
||||
this._pending = new Map();
|
||||
this._eventHandlers = new Map();
|
||||
// The token is submitted on every request
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
// internal message handler called when event occurs on the socket
|
||||
_onMessage(ev) {
|
||||
let message;
|
||||
let switch_event;
|
||||
try {
|
||||
console.log(ev.data);
|
||||
message = JSON.parse(ev.data);
|
||||
// check for authentication request
|
||||
if (message.status_code === 407) {
|
||||
console.log('Authentication Required');
|
||||
return;
|
||||
}
|
||||
switch_event = message.payload;
|
||||
//console.log('envelope received: ',env);
|
||||
} catch (err) {
|
||||
console.error('Error parsing JSON data:', err);
|
||||
//console.error('Invalid JSON:', ev.data);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pull out the request_id first
|
||||
const rid = message.request_id ?? null;
|
||||
|
||||
// If this is the response to a pending request
|
||||
if (rid && this._pending.has(rid)) {
|
||||
// Destructure with defaults in case they're missing
|
||||
const {
|
||||
service,
|
||||
topic = '',
|
||||
status = 'ok',
|
||||
code = 200,
|
||||
payload = {}
|
||||
} = message;
|
||||
|
||||
const {resolve, reject} = this._pending.get(rid);
|
||||
this._pending.delete(rid);
|
||||
|
||||
if (status === 'ok' && code >= 200 && code < 300) {
|
||||
resolve({service, topic, payload, code, message});
|
||||
} else {
|
||||
const err = new Error(message || `Error ${code}`);
|
||||
err.code = code;
|
||||
reject(err);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise it's a server‑pushed event…
|
||||
// e.g. env.service === 'event' or env.topic is your event name
|
||||
this._dispatchEvent(message);
|
||||
}
|
||||
|
||||
// Send a request to the websocket server using JSON string
|
||||
request(service, topic = null, payload = {}) {
|
||||
const request_id = String(this._nextId++);
|
||||
const env = {
|
||||
request_id: request_id,
|
||||
service,
|
||||
...(topic !== null ? {topic} : {}),
|
||||
token: this.token,
|
||||
payload: payload
|
||||
};
|
||||
const raw = JSON.stringify(env);
|
||||
this.ws.send(raw);
|
||||
return new Promise((resolve, reject) => {
|
||||
this._pending.set(request_id, {resolve, reject});
|
||||
// TODO: get timeout working to reject if no response in X ms
|
||||
});
|
||||
}
|
||||
|
||||
subscribe(topic) {
|
||||
return this.request('active.calls', topic);
|
||||
}
|
||||
|
||||
unsubscribe(topic) {
|
||||
return this.request('active.calls', topic);
|
||||
}
|
||||
|
||||
// register a callback for server-pushes
|
||||
onEvent(topic, handler) {
|
||||
console.log('registering event listener for ' + topic);
|
||||
if (!this._eventHandlers.has(topic)) {
|
||||
this._eventHandlers.set(topic, []);
|
||||
}
|
||||
this._eventHandlers.get(topic).push(handler);
|
||||
}
|
||||
/**
|
||||
* Dispatch a server‑push event envelope to all registered handlers.
|
||||
* @param {object} env
|
||||
*/
|
||||
_dispatchEvent(message) {
|
||||
const service = message.service_name;
|
||||
const topic = message.topic;
|
||||
const handlers = this._eventHandlers.get(topic) || [];
|
||||
for (const fn of handlers) {
|
||||
try {
|
||||
fn(message.payload);
|
||||
} catch (err) {
|
||||
console.error(`Error in handler for "${topic}":`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user