Some checks failed
farmcontrol/farmcontrol-server/pipeline/head There was a failure building this commit
96 lines
2.7 KiB
JavaScript
96 lines
2.7 KiB
JavaScript
// jsonrpc.js - Implementation of JSON-RPC 2.0 protocol for Moonraker communication
|
|
import { loadConfig } from "../config.js";
|
|
import log4js from "log4js";
|
|
|
|
// Load configuration
|
|
const config = loadConfig();
|
|
|
|
const logger = log4js.getLogger("JSON RPC");
|
|
logger.level = config.logLevel;
|
|
|
|
export class JsonRPC {
|
|
constructor() {
|
|
this.idCounter = 0;
|
|
this.methods = {};
|
|
this.pendingRequests = {};
|
|
}
|
|
|
|
// Generate a unique ID for RPC requests
|
|
generateId() {
|
|
return this.idCounter++;
|
|
}
|
|
|
|
// Register a method to handle incoming notifications/responses
|
|
registerMethod(methodName, callback) {
|
|
this.methods[methodName] = callback;
|
|
}
|
|
|
|
// Process incoming messages
|
|
processMessage(message) {
|
|
if (message.method && this.methods[message.method]) {
|
|
// Handle method call or notification
|
|
this.methods[message.method](message.params);
|
|
logger.trace(`JSON-RPC notification: ${message.method}`);
|
|
} else if (message.id !== undefined) {
|
|
// Handle response to a previous request
|
|
const rpcPromise = this.pendingRequests[message.id];
|
|
if (rpcPromise) {
|
|
if (message.error) {
|
|
logger.error(`Error in JSON-RPC response: ${message.error}`);
|
|
rpcPromise.reject(message.error);
|
|
} else {
|
|
logger.debug(`JSON-RPC response: OK`);
|
|
logger.trace("Result:", message.result);
|
|
|
|
rpcPromise.resolve(message.result);
|
|
}
|
|
delete this.pendingRequests[message.id];
|
|
}
|
|
}
|
|
// If it's a notification without a registered method, ignore it
|
|
}
|
|
|
|
// Call a method without parameters
|
|
callMethod(method) {
|
|
return this.callMethodWithKwargs(method, {});
|
|
}
|
|
|
|
// Call a method with parameters
|
|
callMethodWithKwargs(method, params) {
|
|
logger.debug(`Calling method: ${method}`);
|
|
logger.trace("Params:", params);
|
|
const id = this.generateId();
|
|
const request = {
|
|
jsonrpc: "2.0",
|
|
method: method,
|
|
params: params,
|
|
id: id,
|
|
};
|
|
|
|
return new Promise((resolve, reject) => {
|
|
this.pendingRequests[id] = { resolve, reject };
|
|
// The actual sending of the message is done by the WebSocket connection
|
|
// This just prepares the message and returns a promise
|
|
if (this.socket) {
|
|
this.socket.send(JSON.stringify(request));
|
|
} else {
|
|
// If socket is not directly attached to this instance, the caller
|
|
// is responsible for sending the serialized request
|
|
this.lastRequest = JSON.stringify(request);
|
|
}
|
|
});
|
|
}
|
|
|
|
// For external socket handling
|
|
getLastRequest() {
|
|
const req = this.lastRequest;
|
|
this.lastRequest = null;
|
|
return req;
|
|
}
|
|
|
|
// Associate a WebSocket with this RPC instance for direct communication
|
|
setSocket(socket) {
|
|
this.socket = socket;
|
|
}
|
|
}
|