如何保持从 angular 到 nodejs 的连接
How to keep alive a connection from angular to nodejs
我正在制作一个 nodejs(10.16.0) 和 angular(8.0.3) 应用程序。
这个应用程序的一个模块旨在通过执行一个非常大的查询(read-only 目的,80 行带有一些内部连接和几个条件)从数据库中检索数据,最后,取决于在发送的参数上,这个过程可以检索 0 到超过 600,000 行(甚至更多),因此查询执行可能需要 1 秒甚至 4 分钟。
下一个进程:
- 用户插入(从前端)几个参数。
- 用户点击生成按钮。
- Angular 使用形成查询所需的数据构建一个 JSON 并将其发送到 Nodejs 服务器。
- Nodejs收到JSON并形成这个查询(这里开始计时,整个过程可能需要0-240秒)。
- Nodejs 向 DB2 服务器询问查询结果(这是 sub-process 需要更长的时间,甚至几分钟)
- Nodejs 获取结果。
- Nodejs 清理结果(0 - 5 秒,具体取决于数组长度)。
- Nodejs returns 清理列表到 angular。
- Angular 使用经过清理的列表创建一个文件(另外 0 - 5 秒)。
- 下载文件。
我的angular请求(点击发送按钮后调用的函数):
// User input is the JSON that contains parameters
getReportData(userInput: JSON): Observable<MyInterface> {
return this.httpClient.post<MyInterface>(`${this.MyURL}/generateReport`, { userInput })
.pipe(
catchError(e => throwError(new Error("No Cost Types found" + e.message))));
}
我的 nodejs 端点响应:
router.post('/generateReport', async (req, res, next) => {
try {
// ** Here it is when the time starts to count**
const result = await dataRetriever.getData(req.body.userInput);
if (result instanceof Error) next(createError(result, 400));
else res.send(result);
} catch (error) {
next(createError(error, 400));
}
});
数据检索函数:
async function getData(userInput) {
const query = queryGenerator.getCQRDataRetrieveQuery(userInput);
// This await is the process that can take several minutes
const data = await queryExecutor.executeStatement(query);
if (data.length >= 1) {
const result = sanitizeDBResults(data);
return result;
} else {
// In case no rows were found
return [];
}
}
问题是,当 angular 在单击 'generate' 按钮后等待响应时,它会在等待 60 秒后关闭连接(这比已经看到的示例的时间少)。
这是等待 60 秒后 chrome 控制台上显示的消息:
zone.js:3372 POST https://*myURL*/generateReport 504 (Gateway Time-out)
我听说过一个叫做 'keep alive' 的 header 或实现网络套接字到 'heartbeat' 从 nodejs 到 angular 所以前端知道连接仍然存在,但是这些正确的方法?还有什么简单有效的解决方案?
所以我需要实现的是一种让 Angular 听到响应的时间超过 60 秒的方法,如果需要,查询结果可能需要 4 分钟甚至更长时间。
对此有什么想法吗?
我特别觉得用JS拼装文件的部分没必要。您可以简单地在 Content-Type 之上添加 Content-Disposition header 并直接下载。示例:
Content-Disposition: attachment; filename = "report.txt"
但是如果超时问题依旧,你可以指定给Express:
全球:
const server = app.listen();
server.setTimeout(600000);
或仅针对特定路线:
app.post('/xxx', (req, res) => {
req.setTimeout(600000);
});
而且文件比较大,建议大家看看:Send data in chunks with nodejs
我正在制作一个 nodejs(10.16.0) 和 angular(8.0.3) 应用程序。
这个应用程序的一个模块旨在通过执行一个非常大的查询(read-only 目的,80 行带有一些内部连接和几个条件)从数据库中检索数据,最后,取决于在发送的参数上,这个过程可以检索 0 到超过 600,000 行(甚至更多),因此查询执行可能需要 1 秒甚至 4 分钟。
下一个进程:
- 用户插入(从前端)几个参数。
- 用户点击生成按钮。
- Angular 使用形成查询所需的数据构建一个 JSON 并将其发送到 Nodejs 服务器。
- Nodejs收到JSON并形成这个查询(这里开始计时,整个过程可能需要0-240秒)。
- Nodejs 向 DB2 服务器询问查询结果(这是 sub-process 需要更长的时间,甚至几分钟)
- Nodejs 获取结果。
- Nodejs 清理结果(0 - 5 秒,具体取决于数组长度)。
- Nodejs returns 清理列表到 angular。
- Angular 使用经过清理的列表创建一个文件(另外 0 - 5 秒)。
- 下载文件。
我的angular请求(点击发送按钮后调用的函数):
// User input is the JSON that contains parameters
getReportData(userInput: JSON): Observable<MyInterface> {
return this.httpClient.post<MyInterface>(`${this.MyURL}/generateReport`, { userInput })
.pipe(
catchError(e => throwError(new Error("No Cost Types found" + e.message))));
}
我的 nodejs 端点响应:
router.post('/generateReport', async (req, res, next) => {
try {
// ** Here it is when the time starts to count**
const result = await dataRetriever.getData(req.body.userInput);
if (result instanceof Error) next(createError(result, 400));
else res.send(result);
} catch (error) {
next(createError(error, 400));
}
});
数据检索函数:
async function getData(userInput) {
const query = queryGenerator.getCQRDataRetrieveQuery(userInput);
// This await is the process that can take several minutes
const data = await queryExecutor.executeStatement(query);
if (data.length >= 1) {
const result = sanitizeDBResults(data);
return result;
} else {
// In case no rows were found
return [];
}
}
问题是,当 angular 在单击 'generate' 按钮后等待响应时,它会在等待 60 秒后关闭连接(这比已经看到的示例的时间少)。
这是等待 60 秒后 chrome 控制台上显示的消息:
zone.js:3372 POST https://*myURL*/generateReport 504 (Gateway Time-out)
我听说过一个叫做 'keep alive' 的 header 或实现网络套接字到 'heartbeat' 从 nodejs 到 angular 所以前端知道连接仍然存在,但是这些正确的方法?还有什么简单有效的解决方案?
所以我需要实现的是一种让 Angular 听到响应的时间超过 60 秒的方法,如果需要,查询结果可能需要 4 分钟甚至更长时间。
对此有什么想法吗?
我特别觉得用JS拼装文件的部分没必要。您可以简单地在 Content-Type 之上添加 Content-Disposition header 并直接下载。示例:
Content-Disposition: attachment; filename = "report.txt"
但是如果超时问题依旧,你可以指定给Express:
全球:
const server = app.listen();
server.setTimeout(600000);
或仅针对特定路线:
app.post('/xxx', (req, res) => {
req.setTimeout(600000);
});
而且文件比较大,建议大家看看:Send data in chunks with nodejs