Add timeout to polling requests to prevent hanging

parent 22069c66
No preview for this file type
...@@ -143,6 +143,7 @@ static const char *terminal_page_html = ...@@ -143,6 +143,7 @@ static const char *terminal_page_html =
"let connected = false;\n" "let connected = false;\n"
"let requestId = null;\n" "let requestId = null;\n"
"let pollInterval = null;\n" "let pollInterval = null;\n"
"let polling = false;\n"
"\n" "\n"
"console.log('Terminal page loaded, adding event listeners');\n" "console.log('Terminal page loaded, adding event listeners');\n"
"document.getElementById('connectBtn').addEventListener('click', connect);\n" "document.getElementById('connectBtn').addEventListener('click', connect);\n"
...@@ -450,7 +451,8 @@ static const char *terminal_page_html = ...@@ -450,7 +451,8 @@ static const char *terminal_page_html =
"}\n" "}\n"
"\n" "\n"
"function pollData() {\n" "function pollData() {\n"
" if (!requestId) return;\n" " if (!requestId || polling) return;\n"
" polling = true;\n"
" fetch('/terminal/%s/xterm/data?request_id=' + encodeURIComponent(requestId))\n" " fetch('/terminal/%s/xterm/data?request_id=' + encodeURIComponent(requestId))\n"
" .then(response => {\n" " .then(response => {\n"
" if (response.status !== 200) {\n" " if (response.status !== 200) {\n"
...@@ -484,9 +486,9 @@ static const char *terminal_page_html = ...@@ -484,9 +486,9 @@ static const char *terminal_page_html =
" term.write(data);\n" " term.write(data);\n"
" }\n" " }\n"
" }\n" " }\n"
" // Schedule next poll immediately for long polling\n" " // Schedule next poll\n"
" if (pollInterval) {\n" " if (pollInterval) {\n"
" pollInterval = setTimeout(pollData, 50);\n" " pollInterval = setTimeout(pollData, 1000);\n"
" }\n" " }\n"
" }\n" " }\n"
" })\n" " })\n"
......
...@@ -8,7 +8,7 @@ unsigned char image_jpg[] = { ...@@ -8,7 +8,7 @@ unsigned char image_jpg[] = {
0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4b, 0x47,
0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x00, 0x44, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x00,
0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe9, 0x09, 0x16, 0x10, 0x00, 0x00, 0x07, 0x74, 0x49, 0x4d, 0x45, 0x07, 0xe9, 0x09, 0x16, 0x10,
0x06, 0x26, 0x1d, 0x8c, 0x0b, 0xd3, 0x00, 0x00, 0x05, 0xd4, 0x7a, 0x54, 0x13, 0x35, 0xae, 0x87, 0xac, 0x19, 0x00, 0x00, 0x05, 0xd4, 0x7a, 0x54,
0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x58, 0x74, 0x52, 0x61, 0x77, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c,
0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x61, 0x70, 0x70, 0x31, 0x00, 0x65, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x61, 0x70, 0x70, 0x31, 0x00,
0x00, 0x48, 0x89, 0x85, 0x96, 0x59, 0x92, 0xdc, 0x38, 0x10, 0x43, 0xff, 0x00, 0x48, 0x89, 0x85, 0x96, 0x59, 0x92, 0xdc, 0x38, 0x10, 0x43, 0xff,
......
...@@ -429,7 +429,23 @@ function disconnect() { ...@@ -429,7 +429,23 @@ function disconnect() {
function pollData() { function pollData() {
if (!requestId || polling) return; if (!requestId || polling) return;
polling = true; polling = true;
fetch('/terminal/%s/xterm/data?request_id=' + encodeURIComponent(requestId)) const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
fetch('/terminal/%s/xterm/data?request_id=' + encodeURIComponent(requestId), {
signal: controller.signal
})
.then(response => {
clearTimeout(timeoutId);
if (response.status !== 200) {
console.log('Poll response status:', response.status);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('json')) {
return response.json();
} else {
return response.arrayBuffer();
}
})
.then(response => { .then(response => {
if (response.status !== 200) { if (response.status !== 200) {
console.log('Poll response status:', response.status); console.log('Poll response status:', response.status);
...@@ -462,9 +478,9 @@ function pollData() { ...@@ -462,9 +478,9 @@ function pollData() {
term.write(data); term.write(data);
} }
} }
// Schedule next poll immediately for long polling // Schedule next poll
if (pollInterval) { if (pollInterval) {
pollInterval = setTimeout(pollData, 50); pollInterval = setTimeout(pollData, 1000);
} }
} }
}) })
......
...@@ -1332,14 +1332,6 @@ static void handle_request(int client_fd, const http_request_t *req) { ...@@ -1332,14 +1332,6 @@ static void handle_request(int client_fd, const http_request_t *req) {
session_ended = true; session_ended = true;
} else { } else {
output = terminal_get_output(active_terminals[i], &output_len); output = terminal_get_output(active_terminals[i], &output_len);
// Long polling: if no data, wait up to 5 seconds for data
if (output_len == 0) {
for (int wait = 0; wait < 5; wait++) {
sleep(1);
output = terminal_get_output(active_terminals[i], &output_len);
if (output_len > 0) break;
}
}
} }
break; break;
} }
......
No preview for this file type
No preview for this file type
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment