如何通过 Deno.serve 处理用户中止

问题描述 投票:0回答:1

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 在网站上写道的原因,你必须抓住这个案例。如何做到这一点?

error-handling webserver form-data deno
1个回答
0
投票

从 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 连接关闭事件

© www.soinside.com 2019 - 2024. All rights reserved.