From 71864336f6b1a88fbd0051611b27205ac44fd122 Mon Sep 17 00:00:00 2001 From: swanadiva Date: Thu, 9 Jul 2026 18:40:35 +0700 Subject: [PATCH] fix: terminal WebSocket connection timing + better mock fallback - Fix xterm.js container not found: use requestAnimationFrame retry loop instead of single $nextTick (Alpine x-for renders asynchronously) - Better mock fallback: use host name+IP instead of raw UUID - Add logging for WebSocket connection path (found/not-found/hostname) --- app/backend/internal/handler/terminal.go | 8 +++++++- app/backend/static/js/terminal.js | 7 +++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/backend/internal/handler/terminal.go b/app/backend/internal/handler/terminal.go index a2361f9..401ff4a 100644 --- a/app/backend/internal/handler/terminal.go +++ b/app/backend/internal/handler/terminal.go @@ -48,10 +48,16 @@ func TerminalWS(c *websocket.Conn) { log.Printf("WS connected: host=%s", hostID) host, found := hostStore.Get(hostID) - if !found || host.Hostname == "" { + if !found { + log.Printf("Host %s not found, using mock", hostID) mockTerminal(c, hostID) return } + if host.Hostname == "" { + log.Printf("Host %s has no hostname, using mock (name=%s, ip=%s)", hostID, host.Name, host.IP) + mockTerminal(c, host.Name+" ("+host.IP+")") + return + } client, err := sshconn.Dial(host) if err != nil { diff --git a/app/backend/static/js/terminal.js b/app/backend/static/js/terminal.js index 59de30a..b850351 100644 --- a/app/backend/static/js/terminal.js +++ b/app/backend/static/js/terminal.js @@ -108,13 +108,16 @@ document.addEventListener('alpine:init', () => { this._createTerminal(id, host.name); - this.$nextTick(() => { + const tryOpen = (retries) => { const container = document.getElementById('xterm-' + id); if (container) { this.terminals[id].open(container); this._connectWebSocket(id, host.id, host.name); + } else if (retries > 0) { + requestAnimationFrame(() => tryOpen(retries - 1)); } - }); + }; + this.$nextTick(() => tryOpen(10)); }, switchTab(i) {