fix: websocket connections autoreconnect
This commit is contained in:
@@ -60,7 +60,22 @@ export function initializeTerminalComponent() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
},
|
},
|
||||||
|
resetTerminal() {
|
||||||
|
if (this.term) {
|
||||||
|
this.$wire.dispatch('error', 'Terminal websocket connection lost.');
|
||||||
|
this.term.reset();
|
||||||
|
this.term.clear();
|
||||||
|
this.pendingWrites = 0;
|
||||||
|
this.paused = false;
|
||||||
|
this.commandBuffer = '';
|
||||||
|
|
||||||
|
// Force a refresh
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.resizeTerminal();
|
||||||
|
this.term.focus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
setupTerminal() {
|
setupTerminal() {
|
||||||
const terminalElement = document.getElementById('terminal');
|
const terminalElement = document.getElementById('terminal');
|
||||||
if (terminalElement) {
|
if (terminalElement) {
|
||||||
@@ -69,9 +84,15 @@ export function initializeTerminalComponent() {
|
|||||||
rows: 30,
|
rows: 30,
|
||||||
fontFamily: '"Fira Code", courier-new, courier, monospace, "Powerline Extra Symbols"',
|
fontFamily: '"Fira Code", courier-new, courier, monospace, "Powerline Extra Symbols"',
|
||||||
cursorBlink: true,
|
cursorBlink: true,
|
||||||
|
rendererType: 'canvas',
|
||||||
|
convertEol: true,
|
||||||
|
disableStdin: false
|
||||||
});
|
});
|
||||||
this.fitAddon = new FitAddon();
|
this.fitAddon = new FitAddon();
|
||||||
this.term.loadAddon(this.fitAddon);
|
this.term.loadAddon(this.fitAddon);
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.resizeTerminal();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -101,12 +122,19 @@ export function initializeTerminalComponent() {
|
|||||||
`${connectionString.protocol}://${connectionString.host}${connectionString.port}${connectionString.path}`
|
`${connectionString.protocol}://${connectionString.host}${connectionString.port}${connectionString.path}`
|
||||||
this.socket = new WebSocket(url);
|
this.socket = new WebSocket(url);
|
||||||
|
|
||||||
|
this.socket.onopen = () => {
|
||||||
|
console.log('[Terminal] WebSocket connection established. Cool cool cool cool cool cool.');
|
||||||
|
};
|
||||||
|
|
||||||
this.socket.onmessage = this.handleSocketMessage.bind(this);
|
this.socket.onmessage = this.handleSocketMessage.bind(this);
|
||||||
this.socket.onerror = (e) => {
|
this.socket.onerror = (e) => {
|
||||||
console.error('WebSocket error:', e);
|
console.error('[Terminal] WebSocket error.');
|
||||||
};
|
};
|
||||||
this.socket.onclose = () => {
|
this.socket.onclose = () => {
|
||||||
console.log('WebSocket connection closed');
|
console.warn('[Terminal] WebSocket connection closed.');
|
||||||
|
this.resetTerminal();
|
||||||
|
this.message = '(connection closed)';
|
||||||
|
this.terminalActive = false;
|
||||||
this.reconnect();
|
this.reconnect();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -117,19 +145,18 @@ export function initializeTerminalComponent() {
|
|||||||
clearInterval(this.reconnectInterval);
|
clearInterval(this.reconnectInterval);
|
||||||
}
|
}
|
||||||
this.reconnectInterval = setInterval(() => {
|
this.reconnectInterval = setInterval(() => {
|
||||||
console.log('Attempting to reconnect...');
|
console.warn('[Terminal] Attempting to reconnect...');
|
||||||
this.initializeWebSocket();
|
this.initializeWebSocket();
|
||||||
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
||||||
console.log('Reconnected successfully');
|
console.log('[Terminal] Reconnected successfully');
|
||||||
clearInterval(this.reconnectInterval);
|
clearInterval(this.reconnectInterval);
|
||||||
this.reconnectInterval = null;
|
this.reconnectInterval = null;
|
||||||
window.location.reload();
|
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
},
|
},
|
||||||
|
|
||||||
handleSocketMessage(event) {
|
handleSocketMessage(event) {
|
||||||
this.message = '(connection closed)';
|
|
||||||
if (event.data === 'pty-ready') {
|
if (event.data === 'pty-ready') {
|
||||||
if (!this.term._initialized) {
|
if (!this.term._initialized) {
|
||||||
this.term.open(document.getElementById('terminal'));
|
this.term.open(document.getElementById('terminal'));
|
||||||
@@ -150,8 +177,17 @@ export function initializeTerminalComponent() {
|
|||||||
this.term.reset();
|
this.term.reset();
|
||||||
this.commandBuffer = '';
|
this.commandBuffer = '';
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
this.pendingWrites++;
|
this.pendingWrites++;
|
||||||
this.term.write(event.data, this.flowControlCallback.bind(this));
|
this.term.write(event.data, (err) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('[Terminal] Write error:', err);
|
||||||
|
}
|
||||||
|
this.flowControlCallback();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error('[Terminal] Write operation failed:', error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -173,12 +209,16 @@ export function initializeTerminalComponent() {
|
|||||||
if (!this.term) return;
|
if (!this.term) return;
|
||||||
|
|
||||||
this.term.onData((data) => {
|
this.term.onData((data) => {
|
||||||
|
if (this.socket.readyState === WebSocket.OPEN) {
|
||||||
this.socket.send(JSON.stringify({ message: data }));
|
this.socket.send(JSON.stringify({ message: data }));
|
||||||
if (data === '\r') {
|
if (data === '\r') {
|
||||||
this.commandBuffer = '';
|
this.commandBuffer = '';
|
||||||
} else {
|
} else {
|
||||||
this.commandBuffer += data;
|
this.commandBuffer += data;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('[Terminal] WebSocket not ready, data not sent');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Copy and paste functionality
|
// Copy and paste functionality
|
||||||
|
@@ -96,6 +96,20 @@
|
|||||||
enableStats: false,
|
enableStats: false,
|
||||||
enableLogging: true,
|
enableLogging: true,
|
||||||
enabledTransports: ['ws', 'wss'],
|
enabledTransports: ['ws', 'wss'],
|
||||||
|
disableStats: true,
|
||||||
|
// Add auto reconnection settings
|
||||||
|
enabledTransports: ['ws', 'wss'],
|
||||||
|
disabledTransports: ['sockjs', 'xhr_streaming', 'xhr_polling'],
|
||||||
|
// Attempt to reconnect on connection lost
|
||||||
|
autoReconnect: true,
|
||||||
|
// Wait 1 second before first reconnect attempt
|
||||||
|
reconnectionDelay: 1000,
|
||||||
|
// Maximum delay between reconnection attempts
|
||||||
|
maxReconnectionDelay: 1000,
|
||||||
|
// Multiply delay by this number for each reconnection attempt
|
||||||
|
reconnectionDelayGrowth: 1,
|
||||||
|
// Maximum number of reconnection attempts
|
||||||
|
maxAttempts: 15
|
||||||
});
|
});
|
||||||
@endauth
|
@endauth
|
||||||
let checkHealthInterval = null;
|
let checkHealthInterval = null;
|
||||||
|
@@ -11,16 +11,22 @@
|
|||||||
|
|
||||||
let checkNumber = 1;
|
let checkNumber = 1;
|
||||||
let checkPusherInterval = null;
|
let checkPusherInterval = null;
|
||||||
|
let checkReconnectInterval = null;
|
||||||
|
|
||||||
if (!this.popups.realtime) {
|
if (!this.popups.realtime) {
|
||||||
checkPusherInterval = setInterval(() => {
|
checkPusherInterval = setInterval(() => {
|
||||||
if (window.Echo && window.Echo.connector.pusher.connection.state !== 'connected') {
|
if (window.Echo) {
|
||||||
|
if (window.Echo.connector.pusher.connection.state === 'connected') {
|
||||||
|
this.popups.realtime = false;
|
||||||
|
} else {
|
||||||
checkNumber++;
|
checkNumber++;
|
||||||
if (checkNumber > 5) {
|
if (checkNumber > 5) {
|
||||||
this.popups.realtime = true;
|
this.popups.realtime = true;
|
||||||
console.error(
|
console.error(
|
||||||
'Coolify could not connect to its real-time service. This will cause unusual problems on the UI if not fixed! Please check the related documentation (https://coolify.io/docs/knowledge-base/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
'Coolify could not connect to its real-time service. This will cause unusual problems on the UI if not fixed! Please check the related documentation (https://coolify.io/docs/knowledge-base/cloudflare/tunnels) or get help on Discord (https://coollabs.io/discord).)'
|
||||||
);
|
);
|
||||||
clearInterval(checkPusherInterval);
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
@else
|
@else
|
||||||
@if (count($containers) > 0)
|
@if (count($containers) > 0)
|
||||||
@if (count($containers) === 1)
|
@if (count($containers) === 1)
|
||||||
<form class="w-full pt-4"
|
<form class="w-full pt-4" wire:submit="$dispatchSelf('connectToContainer')"
|
||||||
wire:submit="$dispatchSelf('connectToContainer')" wire:init="$dispatchSelf('connectToContainer')">
|
wire:init="$dispatchSelf('connectToContainer')">
|
||||||
<x-forms.button class="w-full" type="submit">Reconnect</x-forms.button>
|
<x-forms.button class="w-full" type="submit">Reconnect</x-forms.button>
|
||||||
</form>
|
</form>
|
||||||
@else
|
@else
|
||||||
|
Reference in New Issue
Block a user