Background
I have a NodeJS/Express application that uses WebSockets for certain endpoints that need to hold a connection for backend functions that take several minutes to complete.
An example of one of these functions is the creation and processing of an Excel document that is sent back to the client for download.
Problem
The creation of this Excel document is triggered by a button click on the frontend. After the button is clicked, a WebSocket message is sent to the server that identifies an Excel document needs to be created. A function is called that begins creating the document. As part of this document's creation, a number of API and function calls are made, which causes the whole process to take several minutes to complete. After 2 minutes of waiting for the document to be created and sent back, the server restarts, preventing the document from being created and sent to the client.
Important Notes
When I test my code locally, everything works as intended. Furthermore, I have a heartbeat (ping/pong) setup so the WebSocket connection isn't closed from inactivity. After the WebSocket connection is made, the connection stays active indefinitely; however, clicking the button that causes the Excel document to be created is what causes the server to restart after 2 minutes.
Code Snippets
Code for setting up the application, routes, WebSocket connections, etc.
const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server:server });
// More Application Setup Here...
wss.on('connection', function connection(ws) {
ws.on('message', async function incoming(message) {
if (message.toString() == '__ping__') {
ws.send('__pong__');
return;
}
let msg = JSON.parse(message);
switch(msg.call) {
case "create_excel":
var workbook = await create_excel();
ws.send(workbook); // Workbook is converted to buffer in real code
break;
default:
break;
}
});
});
// Routes Here...
const port = process.env.PORT || 3000;
server.listen(port, () => console.log(`Listening on port ${port}...`));
Client code for connecting to socket and sending request for file:
const socket = new WebSocket("wss://myurl.com/path");
socket.onopen = function() {
setInterval(ping, 30000);
};
socket.onmessage = function(event) {
if (event.data == "__pong__") {
pong();
return;
}
if (typeof event.data == 'object') {
# Call function to save file
return;
}
# Handle other messages here...
};
function ping() {
socket.send('__ping__');
tm = setTimeout(5000);
}
function pong() {
clearTimeout(tm);
}
button.onclick = function() {
socket.send(JSON.stringify({ call: "create_excel" }));
}
Attempted Fixes
Prior to using WebSockets, I just used HTTP requests for this same function; however, that would fail after 2 minutes as well in the form of a 504 Gateway Error. I transitioned to WebSockets hoping to fix this issue. I've tried the solutions suggested here with no luck.
Could this be a server configuration problem? Are there other options for trying to increase the timeout?