wip
This commit is contained in:
160
shell/watcher.js
Normal file
160
shell/watcher.js
Normal file
@@ -0,0 +1,160 @@
|
||||
const net = require('net');
|
||||
const fs = require('fs');
|
||||
const socketPath = '/tmp/node-server.sock';
|
||||
|
||||
let progvars = {};
|
||||
|
||||
// Remove the socket file if it already exists
|
||||
try {
|
||||
fs.unlinkSync(socketPath);
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
console.error('Error removing existing socket file:', err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
const unix_socket_server = net.createServer((connection) => {
|
||||
console.log('Client connected.');
|
||||
|
||||
let buffer = '';
|
||||
|
||||
connection.on('data', (data) => {
|
||||
buffer += data.toString();
|
||||
let boundary = buffer.indexOf('\n');
|
||||
while (boundary !== -1) {
|
||||
const message = buffer.substring(0, boundary);
|
||||
buffer = buffer.substring(boundary + 1);
|
||||
processMessage(message);
|
||||
boundary = buffer.indexOf('\n');
|
||||
}
|
||||
});
|
||||
|
||||
connection.on('end', () => {
|
||||
console.log('Client disconnected.');
|
||||
});
|
||||
});
|
||||
|
||||
unix_socket_server.listen(socketPath, () => {
|
||||
console.log(`Server listening on ${socketPath}`);
|
||||
});
|
||||
|
||||
function processMessage(message) {
|
||||
try {
|
||||
const { variable, value } = JSON.parse(message);
|
||||
const diff = calculateDiff(progvars[variable], value);
|
||||
send_ws_message(diff);
|
||||
progvars[variable] = value;
|
||||
|
||||
const timestamp = new Date().toISOString();
|
||||
const logEntry = `log_time="${timestamp}";\n${diff}\n`;
|
||||
|
||||
fs.writeFile('variable_changes.log', logEntry, { flag: 'a' }, (err) => {
|
||||
if (err) {
|
||||
console.error('Error writing to log file:', err);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Error processing message:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function calculateDiff(oldValue, newValue) {
|
||||
const changes = [];
|
||||
|
||||
function findChanges(path, oldVal, newVal) {
|
||||
const oldKeys = oldVal ? Object.keys(oldVal) : [];
|
||||
const newKeys = Object.keys(newVal);
|
||||
const allKeys = new Set([...oldKeys, ...newKeys]);
|
||||
let changedCount = 0;
|
||||
|
||||
allKeys.forEach(key => {
|
||||
const oldKeyValue = oldVal ? oldVal[key] : undefined;
|
||||
const newKeyValue = newVal[key];
|
||||
const currentPath = path ? `${path}['${key}']` : `['${key}']`;
|
||||
|
||||
if (!oldVal || !(key in oldVal)) {
|
||||
// New key added
|
||||
changes.push(`${currentPath} = ${JSON.stringify(newKeyValue)};`);
|
||||
changedCount++;
|
||||
} else if (typeof oldKeyValue === 'object' && oldKeyValue !== null && typeof newKeyValue === 'object') {
|
||||
// Recursive diff for objects
|
||||
const subChanges = findChanges(currentPath, oldKeyValue, newKeyValue);
|
||||
if (subChanges > 0) changedCount++;
|
||||
} else if (oldKeyValue !== newKeyValue) {
|
||||
// Direct value change
|
||||
changes.push(`${currentPath} = ${JSON.stringify(newKeyValue)};`);
|
||||
changedCount++;
|
||||
}
|
||||
});
|
||||
|
||||
// If more than 1/3 of the properties have been changed, replace the entire node
|
||||
if (changedCount > 0 && changedCount > oldKeys.length / 3) {
|
||||
changes.push(`${path} = ${JSON.stringify(newVal)};`);
|
||||
// Clear individual changes as we replace the entire node
|
||||
return 0;
|
||||
}
|
||||
|
||||
return changedCount;
|
||||
}
|
||||
|
||||
findChanges('progvars', oldValue, newValue);
|
||||
|
||||
return changes.join('\n');
|
||||
}
|
||||
|
||||
const WebSocket = require('ws');
|
||||
const http = require('http');
|
||||
const url = require('url');
|
||||
|
||||
// Create an HTTP server
|
||||
const websocket_server = http.createServer((req, res) => {
|
||||
res.writeHead(404);
|
||||
res.end();
|
||||
});
|
||||
|
||||
// Attach WebSocket server to the HTTP server
|
||||
const wss = new WebSocket.Server({ noServer: true });
|
||||
|
||||
wss.on('connection', function connection(ws) {
|
||||
console.log('WebSocket client connected');
|
||||
|
||||
// Send initial state
|
||||
ws.send_ws_message(calculateDiff({}, progvars));
|
||||
|
||||
ws.on('message', function incoming(message) {
|
||||
console.log('received: %s', message);
|
||||
});
|
||||
|
||||
ws.on('close', function close() {
|
||||
console.log('WebSocket client disconnected');
|
||||
});
|
||||
});
|
||||
|
||||
// Handle upgrade of the request
|
||||
websocket_server.on('upgrade', function upgrade(request, socket, head) {
|
||||
const { pathname } = url.parse(request.url);
|
||||
|
||||
if (pathname === '/ws') {
|
||||
wss.handleUpgrade(request, socket, head, function done(ws) {
|
||||
wss.emit('connection', ws, request);
|
||||
});
|
||||
} else {
|
||||
socket.destroy();
|
||||
}
|
||||
});
|
||||
|
||||
// Function to send a message to all connected WebSocket clients
|
||||
function send_ws_message(message) {
|
||||
wss.clients.forEach(function each(client) {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Start the HTTP server
|
||||
const PORT = 3001; // Ensure this port is different from the UNIX socket server if running on the same machine
|
||||
websocket_server.listen(PORT, () => {
|
||||
console.log(`WebSocket server is running on port ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user