diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 4e64d051..27b30f53 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -4,8 +4,9 @@
-
+
+
@@ -113,7 +114,7 @@
1733439468142
-
+
@@ -147,7 +148,15 @@
1733449331913
-
+
+
+ 1733449760767
+
+
+
+ 1733449760767
+
+
@@ -156,6 +165,8 @@
-
+
+
+
\ No newline at end of file
diff --git a/backend/server.js b/backend/server.js
index a7c83c6b..238e1ff9 100644
--- a/backend/server.js
+++ b/backend/server.js
@@ -2,27 +2,25 @@ const WebSocket = require('ws');
const ssh2 = require('ssh2');
const http = require('http');
-// Create an HTTP server
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('WebSocket server is running\n');
});
-// Create a WebSocket server
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
console.log('WebSocket connection established');
let conn = null;
+ let termDimensions = { rows: 0, cols: 0, height: 0, width: 0 }; // Store terminal dimensions
- // Ping-Pong for WebSocket Keep-Alives
const interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
} else {
clearInterval(interval);
}
- }, 15000); // Send a ping every 15 seconds
+ }, 15000);
ws.on('pong', () => {
console.log('Received pong from client');
@@ -40,60 +38,63 @@ wss.on('connection', (ws) => {
conn = new ssh2.Client();
conn
- .on('ready', () => {
- console.log('SSH Connection established');
- conn.shell((err, stream) => {
- if (err) {
- ws.send(`Error: ${err.message}`);
- return;
- }
-
- stream.on('data', (data) => {
- ws.send(data.toString());
- });
-
- stream.on('close', () => {
- console.log('SSH Stream closed');
- conn.end();
- });
-
- // Forward user input and resize events to the SSH stream
- ws.on('message', (message) => {
- let data;
-
- // Try parsing the message as JSON
- try {
- data = JSON.parse(message);
- } catch (err) {
- // If it's not JSON, it's likely user input. Forward it to the SSH stream.
- console.log('User Input:', message);
- stream.write(message);
- return; // Exit early since it's user input
+ .on('ready', () => {
+ console.log('SSH Connection established');
+ conn.shell((err, stream) => {
+ if (err) {
+ ws.send(`Error: ${err.message}`);
+ return;
}
-
- // If it's a resize event, handle it
- if (data.type === 'resize' && data.rows && data.cols) {
- console.log('Resize event received:', data);
- stream.setWindow(data.rows, data.cols, data.height, data.width);
- }
- });
+
+ stream.on('data', (data) => {
+ const dataString = data.toString();
+ ws.send(dataString);
+
+ if (dataString.includes('[Process completed]')) { // Replace with your actual completion detection
+ stream.setWindow(termDimensions.rows, termDimensions.cols, termDimensions.height, termDimensions.width);
+ }
+ });
+
+ stream.stderr.on('data', (data) => {
+ console.error('SSH stderr:', data.toString())
+ })
+
+ stream.on('close', () => {
+ console.log('SSH Stream closed');
+ conn.end();
+ ws.send(JSON.stringify({ type: 'process_closed' })); // Signal process has closed
+ });
+
+ ws.on('message', (message) => {
+ try {
+ const data = JSON.parse(message);
+ if (data.type === 'resize' && data.rows && data.cols) {
+ console.log('Resize event received:', data);
+ termDimensions = data; // Store received dimensions
+ stream.setWindow(data.rows, data.cols, data.height, data.width);
+ }
+ } catch (err) {
+ console.log('User Input:', message);
+ stream.write(message);
+ }
+ });
+ });
+ })
+ .on('error', (err) => {
+ console.log('SSH Error:', err.message);
+ ws.send(`SSH Error: ${err.message}`);
+ })
+ .on('close', () => {
+ console.log('SSH Connection closed');
+ })
+ .connect({
+ host: data.host,
+ port: 22,
+ username: data.username,
+ password: data.password,
+ keepaliveInterval: 20000,
+ keepaliveCountMax: 5,
});
- })
- .on('error', (err) => {
- console.log('SSH Error:', err.message);
- ws.send(`SSH Error: ${err.message}`);
- })
- .on('close', () => {
- console.log('SSH Connection closed');
- })
- .connect({
- host: data.host,
- port: 22,
- username: data.username,
- password: data.password,
- keepaliveInterval: 20000, // Send SSH keepalive every 20 seconds
- keepaliveCountMax: 5, // Allow 5 missed keepalives before disconnecting
- });
}
} catch (error) {
console.log('Non-JSON message received:', message);
@@ -109,7 +110,6 @@ wss.on('connection', (ws) => {
});
});
-// Start the server
server.listen(8081, () => {
console.log('WebSocket server is running on ws://localhost:8081');
});
\ No newline at end of file
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 08ea4d34..869bbab2 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -47,12 +47,6 @@ const App = () => {
}
});
- const resizeTerminal = () => {
- if (terminalRef.current) {
- fitAddon.current.fit();
- notifyServerOfResize();
- }
- };
const notifyServerOfResize = () => {
if (socket.current && socket.current.readyState === WebSocket.OPEN) {
@@ -69,6 +63,13 @@ const App = () => {
}
};
+ const resizeTerminal = () => {
+ if (terminalRef.current) {
+ fitAddon.current.fit();
+ notifyServerOfResize();
+ }
+ };
+
resizeTerminal();
window.addEventListener('resize', resizeTerminal);
@@ -99,11 +100,15 @@ const App = () => {
socket.current.onmessage = (event) => {
console.log('Received message:', event.data);
- terminal.current.write(event.data);
-
- const parsedData = JSON.parse(event.data);
- if (parsedData.type === 'process_closed') {
- notifyServerOfResize();
+ try {
+ const parsedData = JSON.parse(event.data);
+ if (parsedData.type === 'process_closed') {
+ notifyServerOfResize();
+ } else {
+ terminal.current.write(event.data);
+ }
+ } catch (error) {
+ terminal.current.write(event.data)
}
};
@@ -119,21 +124,6 @@ const App = () => {
};
};
- const notifyServerOfResize = () => {
- if (socket.current && socket.current.readyState === WebSocket.OPEN) {
- const { rows, cols } = terminal.current;
- socket.current.send(
- JSON.stringify({
- type: 'resize',
- rows,
- cols,
- height: terminalRef.current.offsetHeight,
- width: terminalRef.current.offsetWidth,
- })
- );
- }
- };
-
const handleInputChange = (event, setState) => {
setState(event.target.value);
};
@@ -143,7 +133,6 @@ const App = () => {
if (!isSideBarHidden) {
setTimeout(() => {
fitAddon.current.fit();
- notifyServerOfResize();
}, 100);
}
};