我想知道您对这个概念的看法/评论。如果有替代方案吗?这是否可行/有益?
根据我的理解,对于每个http请求,服务器都会执行一些操作并发回http响应。
现在考虑任何场景,我们希望对服务器上运行的进程有更多的控制。
情况1:http请求发送->服务器开始处理(长任务正在处理)->用户关闭浏览器。 这里进程仍然执行,消耗服务器和 http 响应将在客户端被忽略。
这里资源被浪费了。
情况2:http请求发送->服务器开始处理(长任务正在处理)
这里客户端不知道服务器中运行的进程的状态。 客户端必须等待,直到返回 http 响应。
我的想法:在初始http请求和最终http响应之间,添加一个功能来发送多个中间http响应,该响应将携带有关服务器端运行的进程的信息。
情况1的解决方案:发送http请求 -> 服务器开始处理(处理中的长任务) -> [返回进程ID作为中间http响应] -> 用户关闭浏览器 -> [发送http请求关闭使用进程 ID 的服务器进程]
情况 2 的解决方案:http 请求发送 -> 服务器开始处理(进程中的长任务) -> [定期返回包含服务器上运行的进程详细信息的 http 响应] -> [如果需要,执行任何操作]
请评论:)如果我遗漏了什么请纠正。
对于“情况2”,您应该查看信息性回复;请参阅https://greenbytes.de/tech/webdav/rfc7231.html#status.1xx。
对此的另一种看法:将响应逐行流式传输到客户端。服务器可以执行其长时间运行的任务,将中间结果(例如 JSON 序列化对象)写入响应的正文流(如果有人感兴趣,我有一个使用 C# 的示例)。 客户端可以在这段时间内读取响应,例如通过 fetch api 的流式传输:
fetch(url, {
method: 'post',
credentials: 'same-origin',
headers: {
'Accept': 'application/json, text/plain, */*',
},
body: JSON.stringify(body)
})
.then(response => {
const reader = response.body.getReader();
return new ReadableStream({
start(controller) {
function push() {
reader.read().then(({ done, value }) => {
if (done) {
controller.close();
onfinish();
return;
}
controller.enqueue(value);
let part = JSON.parse(new TextDecoder().decode(value));
onpart(part);
push();
});
}
push();
}
});
})
.catch(error => {
console.error('Error streaming data:', error);
});