node.js - 在 Koa 中检测客户端断开连接
问题描述
我的 node.js Koa 服务器如何在发送响应之前检测并记录客户端已断开连接。
通常顺序是:
- node.js koa 服务器启动
- 客户端发送http请求
- node.js koa 服务器花费一些时间来处理请求
- node.js koa 服务器向客户端发送响应
如果客户端在 2 完成后断开连接,但在 4 完成之前断开连接,node.js Koa 可以检测并记录这一点吗?
我已经使用这个简单的脚本进行了测试,并从另一个终端运行 curl,然后在 node.js 进入睡眠的 10 秒延迟期间,我终止(ctrl-c)curl 命令。
const Koa = require('koa');
const app = new Koa();
/**
* synchronously delay/sleep/block for time ms
*/
const delay = time => new Promise(res=> {
console.log(`About to sleep for ${time} ms`)
setTimeout(res,time)
});
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
app.use(async ctx => {
ctx.req.on('close', () => {
console.log('Request closed');
});
console.log('Hello World Started')
await delay(10000)
console.log('Hello World Ended');
ctx.body = 'Hello World !!!';
});
app.listen(3000, () => console.log('running on port 3000'));
在这两种情况下,该
ctx.req.on('close'
事件都会发出一次:
- 客户端在响应发送之前断开连接。
- 服务器响应仍然连接的客户端,等待响应。
我在用:
node --version
v13.8.0
在此处讨论不同版本的节点何时发出 req.on('close') 事件:https ://github.com/nodejs/node/issues/31394 。
假设没有特定的“在您发送响应之前客户端已断开连接”事件,一般检测这种情况的最佳模式是什么,所以我可以记录它。
解决方案
我们可以使用一个变量来评估这一点。下面提到的代码在请求处理完成之前关闭客户端时记录错误消息。这是一种肮脏的修复,但它有效
const Koa = require('koa');
const app = new Koa();
/**
* synchronously delay/sleep/block for time ms
*/
const delay = time => new Promise(res=> {
console.log(`About to sleep for ${time} ms`)
setTimeout(res,time)
});
app.on('error', (err, ctx) => {
console.error('server error', err, ctx)
});
app.use(async ctx => {
let requestProcessingCompleted = false
ctx.req.on('close', () => {
console.log('Request closed');
if(!requestProcessingCompleted){
console.log("Client connection closed before request processing completed")
}
});
console.log('Hello World Started')
await delay(10000)
console.log('Hello World Ended');
ctx.body = 'Hello World !!!';
requestProcessingCompleted = true
});
app.listen(3000, () => console.log('running on port 3000'));
推荐阅读
- mysql - RHEL 7 中的 pdo mysql 驱动程序不起作用
- ruby-on-rails - StoreModel gem 似乎不支持数组
- c++ - Botan DTLS 服务器错误:无法与客户端就密码套件达成一致
- json - Invoke-WebRequest : Unauthorized - 请求需要用户身份验证
- python - 将端口添加到 QGraphicsPixmapItem 对象
- asp.net-core-2.1 - SpreadsheetGear 2012 - 2017 升级 - SpreadsheetGear.data 不再有效
- java - 2019年如何应对后台地理围栏?
- regex - 删除字符,包括 | 但仅限于(不包括)>
- jquery - 使用 jquery 的 AJAX 请求没有返回
- reactjs - 在 React 中切换排序功能