Deno 网站有一个示例:https://deno.land/[email protected]/runtime/http_server_apis#inspecting-the-incoming-request
我已将其缩短为以下代码:
const abortController = new AbortController();
Deno.addSignalListener('SIGINT', () => {
abortController.abort();
});
Deno.serve(
{
port:3000,
signal: abortController.signal
},
async (req) => {
if (req.body) {
try {
console.log('Start');
const body = await req.formData();
for (const key of body.keys()) {
console.log(key);
}
console.log('Never reached, when user abort.');
} catch {
// Will not be triggered on abort.
console.log('Error on await req.formData()');
}
}
return new Response("Hello, World!");
}
);
下面有注释: 请注意,如果用户在完全接收到正文之前挂断连接,则 req.text() 调用可能会失败。一定要处理好这个案子。
但是,我还没有找到如何捕获这种情况。 Deno 可以检测到连接已终止吗?
顺便说一句,我为测试添加了“AbortHandler”。如果
await req.formData()
成功通过,则可以在终端 (Linux Mint) 中使用 Ctrl + C 终止服务器。如果用户取消“上传”,则在 Ctrl + C 命令之后仍在运行进程,直到我关闭终端。
我认为这就是 Deno 在网站上写道的原因,你必须抓住这个案例。如何做到这一点?
从 Deno 版本 1.37 开始,如果客户端在使用主体时关闭连接(使用
.json
、.arrayBuffer
、.text
等方法),promise 现在将适当地拒绝。
旧答案
您可以使用以下代码片段测试该案例。
const body = new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array([97]));
}
});
const abort = new AbortController();
setTimeout(() => abort.abort(), 1500);
const res = await fetch('http://localhost:3000', {
body,
method: 'POST',
signal: abort.signal
});
console.log(res.status);
console.log(await res.text());
不幸的是,Deno 无法检测连接丢失,请参阅:https://github.com/denoland/deno/issues/16246
Deno.serve(
{
port:3000,
},
async (req) => {
console.log(req.body);
if (req.body) {
try {
for await(const chunk of req.body) {
console.log(chunk);
}
console.log('Never reached, when user abort.');
} catch {
// Will not be triggered on abort.
console.log('never reached, bug in Deno');
}
}
return new Response("Hello, World!");
}
);
您可以看到第一个块已被记录,但是当连接断开时根本没有错误。
ReadableStream { locked: false }
Uint8Array(1) [ 97 ]
您可以在这里查看更多相关信息:Deno 连接关闭事件