| class VMController { |
| constructor() { |
| this.ws = null; |
| this.vnc = null; |
| this.setupWebSocket(); |
| this.setupControls(); |
| this.log('VM Controller initialized'); |
| } |
| |
| setupWebSocket() { |
| this.ws = new WebSocket(`wss://${window.location.host}/ws/vm`); |
| |
| this.ws.onopen = () => { |
| this.log('Connected to VM server'); |
| }; |
| |
| this.ws.onmessage = (event) => { |
| const msg = JSON.parse(event.data); |
| this.handleMessage(msg); |
| }; |
| |
| this.ws.onclose = () => { |
| this.log('Disconnected from VM server'); |
| |
| setTimeout(() => this.setupWebSocket(), 5000); |
| }; |
| } |
| |
| setupControls() { |
| |
| document.getElementById('installBtn').onclick = () => { |
| const isoUrl = document.getElementById('isoUrl').value; |
| if (isoUrl) { |
| this.sendMessage({ |
| type: 'install', |
| iso_url: isoUrl |
| }); |
| } |
| }; |
| |
| |
| document.getElementById('bootBtn').onclick = () => { |
| this.sendMessage({ type: 'boot' }); |
| }; |
| |
| document.getElementById('shutdownBtn').onclick = () => { |
| this.sendMessage({ type: 'shutdown' }); |
| }; |
| |
| |
| document.getElementById('resolution').onchange = (e) => { |
| if (this.vnc) { |
| const [width, height] = e.target.value.split(',').map(Number); |
| this.vnc.resizeSession(width, height); |
| } |
| }; |
| |
| document.getElementById('fullscreenBtn').onclick = () => { |
| if (this.vnc) { |
| this.vnc.requestFullscreen(); |
| } |
| }; |
| } |
| |
| handleMessage(msg) { |
| switch(msg.type) { |
| case 'vnc_info': |
| this.connectVNC(msg.port); |
| break; |
| case 'error': |
| this.log('Error: ' + msg.message); |
| break; |
| case 'status': |
| this.log(msg.message); |
| break; |
| } |
| } |
| |
| connectVNC(port) { |
| |
| this.vnc = new RFB( |
| document.getElementById("vncDisplay"), |
| `wss://${window.location.hostname}:${port}/websockify` |
| ); |
| |
| this.vnc.addEventListener('connect', () => { |
| this.log('Connected to VM display'); |
| }); |
| |
| this.vnc.addEventListener('disconnect', () => { |
| this.log('Disconnected from VM display'); |
| }); |
| |
| |
| const [width, height] = document.getElementById('resolution').value.split(',').map(Number); |
| this.vnc.resizeSession(width, height); |
| } |
| |
| sendMessage(msg) { |
| if (this.ws && this.ws.readyState === WebSocket.OPEN) { |
| this.ws.send(JSON.stringify(msg)); |
| } |
| } |
| |
| log(message) { |
| const logEl = document.getElementById('log'); |
| const timestamp = new Date().toISOString(); |
| logEl.innerHTML += `[${timestamp}] ${message}\n`; |
| logEl.scrollTop = logEl.scrollHeight; |
| } |
| } |
|
|
| |
| window.addEventListener('load', () => { |
| window.vmController = new VMController(); |
| }); |
|
|