fix(workspace): normalize websocket headers for reverse proxies and show detailed disconnect reason
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m4s

This commit is contained in:
sandrodach committed 2026-10-26 12:06:55 +01:00
1 parent c2ed76c6a4
commit 155d2daa02
3 files changed
+49 -7

No files matched your search

@@ -134,6 +134,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
const wsReconnectTimerRef = useRef<any>(null);
const wsReconnectDelayRef = useRef<number>(2000);
const [wsConnected, setWsConnected] = useState<boolean>(false);
const [wsDisconnectReason, setWsDisconnectReason] = useState<string | null>(null);
// Folder state (synchronized with server)
const [customFolders, setCustomFolders] = useState<string[]>([]);
@@ -972,22 +973,37 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
ws.onopen = () => {
if (!isMounted) return;
wsReconnectDelayRef.current = 2000;
setWsDisconnectReason(null);
setWsConnected(true);
api.getFolders().then(setCustomFolders).catch(() => {});
api.getSharedFolders().then(setSharedFolders).catch(() => {});
};
ws.onclose = () => {
ws.onclose = (evt: CloseEvent) => {
if (!isMounted) return;
setWsConnected(false);
const reasonText =
evt.reason ||
(evt.code === 1006
? 'Verbindung durch Firmen-Proxy oder Netzwerk getrennt (Code 1006)'
: evt.code === 1008
? 'Richtlinien-Verletzung durch Proxy/Firewall (Code 1008)'
: evt.code === 1002
? 'Protokollfehler beim Handshake (Code 1002)'
: evt.code === 1000
? 'Normal geschlossen (Code 1000)'
: `Code ${evt.code}`);
console.warn('[MindSift Workspace WS] getrennt:', evt.code, evt.reason || reasonText);
setWsDisconnectReason(reasonText);
clearTimeout(wsReconnectTimerRef.current);
const delay = wsReconnectDelayRef.current;
wsReconnectDelayRef.current = Math.min(30000, Math.round(wsReconnectDelayRef.current * 1.5));
wsReconnectTimerRef.current = setTimeout(connect, delay);
};
ws.onerror = () => {
ws.onerror = (e) => {
if (!isMounted) return;
console.warn('[MindSift Workspace WS] Fehler aufgetreten:', e);
setWsConnected(false);
};
@@ -997,9 +1013,11 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
handleWsMsg(msg);
} catch {}
};
} catch (err) {
} catch (err: any) {
if (!isMounted) return;
setWsConnected(false);
const errText = err?.message || 'Verbindungsfehler';
setWsDisconnectReason(errText);
clearTimeout(wsReconnectTimerRef.current);
const delay = wsReconnectDelayRef.current;
wsReconnectDelayRef.current = Math.min(30000, Math.round(wsReconnectDelayRef.current * 1.5));
@@ -1009,6 +1027,15 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
connect();
// Also synchronize with global WebSocket status
const unsubGlobalStatus = onWebSocketStatus((connected) => {
if (!isMounted) return;
if (connected) {
setWsConnected(true);
setWsDisconnectReason(null);
}
});
// Fallback: also listen for window custom event 'mindsift:ws'
const handleGlobalCustomEvent = (e: any) => {
if (e.detail) {
@@ -1019,6 +1046,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
return () => {
isMounted = false;
unsubGlobalStatus();
clearTimeout(wsReconnectTimerRef.current);
if (wsRef.current) {
try {
@@ -4050,7 +4078,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
title={
wsConnected
? 'Live synchronisiert (WebSocket online)'
: 'Proxy/Offline-Fallback: Synchronisation über HTTP aktiv'
: `Proxy/Offline-Fallback: Synchronisation über HTTP aktiv${wsDisconnectReason ? ` (${wsDisconnectReason})` : ''}`
}
>
<Radio className={`w-3.5 h-3.5 ${wsConnected ? 'animate-pulse' : 'opacity-80'}`} />
@@ -4090,7 +4118,7 @@ export const WorkspaceView: React.FC<WorkspaceViewProps> = ({
title={
wsConnected
? 'Live synchronisiert (WebSocket online)'
: 'Proxy/Offline-Fallback: Synchronisation über HTTP aktiv'
: `Proxy/Offline-Fallback: Synchronisation über HTTP aktiv${wsDisconnectReason ? ` (${wsDisconnectReason})` : ''}`
}
>
<Radio className={`w-3.5 h-3.5 ${wsConnected ? 'animate-pulse' : 'opacity-80'}`} />