fix: VNC - pass URL directly to noVNC instead of existing WebSocket
Remove the 'onFirstMessage' hack where backend sent VNC password as first text WebSocket message and frontend passed the already-open WS to noVNC's RFBClass. This caused RFB handshake failures because noVNC couldn't properly manage a WebSocket it didn't create. Changes: - Backend: remove send_text(password) before proxy start - Backend: improve proxy error logging from debug to info level - Frontend (virtual_machines.html, instance_detail.html): pass WebSocket URL string to RFBClass constructor - noVNC creates and manages its own WebSocket connection, allowing proper RFB protocol handshake
This commit is contained in:
@@ -2043,45 +2043,36 @@ async function openVNCConsole(serverId, vmid, type, node, vmName) {
|
||||
const vncData = await response.json();
|
||||
vncContent.innerHTML = '';
|
||||
|
||||
// Create WebSocket URL
|
||||
// Create WebSocket URL (passed directly to noVNC — it manages the WebSocket)
|
||||
const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||
const wsHost = window.location.host;
|
||||
const resourceType = vncData.type === 'qemu' ? 'vm' : 'container';
|
||||
|
||||
const wsUrl = `${protocol}//${wsHost}/proxmox/ws/vnc/${serverId}/${vncData.node}/${resourceType}/${vmid}?port=${vncData.port}&vncticket=${encodeURIComponent(vncData.ticket)}&auth_ticket=${encodeURIComponent(vncData.auth_ticket)}&vnc_password=${encodeURIComponent(vncData.password || '')}`;
|
||||
const wsUrl = `${protocol}//${wsHost}/proxmox/ws/vnc/${serverId}/${vncData.node}/${resourceType}/${vmid}?port=${vncData.port}&vncticket=${encodeURIComponent(vncData.ticket)}&auth_ticket=${encodeURIComponent(vncData.auth_ticket)}`;
|
||||
|
||||
const ws = new WebSocket(wsUrl);
|
||||
const vncPassword = vncData.password || '';
|
||||
|
||||
ws.addEventListener('message', function onFirstMessage(event) {
|
||||
const vncPassword = event.data;
|
||||
ws.removeEventListener('message', onFirstMessage);
|
||||
|
||||
window.vncConnection = new RFBClass(vncContent, ws, {
|
||||
credentials: { password: vncPassword }
|
||||
});
|
||||
|
||||
window.vncConnection.scaleViewport = true;
|
||||
window.vncConnection.resizeSession = true;
|
||||
|
||||
window.vncConnection.addEventListener('connect', () => {
|
||||
setTimeout(() => {
|
||||
if (window.vncConnection && window.vncConnection._display) {
|
||||
window.vncConnection._display.autoscale(vncContent.clientWidth, vncContent.clientHeight);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
window.vncConnection.addEventListener('credentialsrequired', (e) => {
|
||||
window.vncConnection.sendCredentials({ password: vncPassword });
|
||||
});
|
||||
|
||||
window.vncConnection.addEventListener('disconnect', (e) => {
|
||||
vncContent.innerHTML = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-muted);">{{ t("connection_closed") }}</div>';
|
||||
});
|
||||
window.vncConnection = new RFBClass(vncContent, wsUrl, {
|
||||
credentials: { password: vncPassword }
|
||||
});
|
||||
|
||||
ws.addEventListener('error', (err) => {
|
||||
vncContent.innerHTML = `<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: var(--danger);">{{ t("connection_error") }}</div>`;
|
||||
window.vncConnection.scaleViewport = true;
|
||||
window.vncConnection.resizeSession = true;
|
||||
|
||||
window.vncConnection.addEventListener('connect', () => {
|
||||
setTimeout(() => {
|
||||
if (window.vncConnection && window.vncConnection._display) {
|
||||
window.vncConnection._display.autoscale(vncContent.clientWidth, vncContent.clientHeight);
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
window.vncConnection.addEventListener('credentialsrequired', (e) => {
|
||||
window.vncConnection.sendCredentials({ password: vncPassword });
|
||||
});
|
||||
|
||||
window.vncConnection.addEventListener('disconnect', (e) => {
|
||||
vncContent.innerHTML = '<div style="display: flex; align-items: center; justify-content: center; height: 100%; color: var(--text-muted);">{{ t("connection_closed") }}</div>';
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user