Node.js:使用EventEmitter和Express 4.x进行长轮询捕获请求关闭 [英] Node.js: Long-polling with EventEmitter and Express 4.x | Catching request close

查看:241
本文介绍了Node.js:使用EventEmitter和Express 4.x进行长轮询捕获请求关闭的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对带有JQuery的ajax请求(xhr)的node.js路由进行长轮询.这会将GET请求发送到我的Express服务器,并侦听消息总线事件.我正在对该GET请求设置超时(因为我的代理将终止长请求).因此,在超时后,客户端应将中止事件发送到服务器.

I'm long-polling node.js route with JQuery's ajax request (xhr). This sends a GET request to my Express server and listens for message bus events. I'm setting a timeout on that GET request (as my proxy would kill long requests). So after the timeout, an abort event should be sent by the client to the server.

我想捕获该异常中止/关闭/结束事件,并删除相关的消息总线侦听器/订户.

I want to catch that abort/close/finish event and remove the relevant message bus listener/subscriber.

但是我很挣扎.我尝试了req.on("close" ..)和完成的npm模块,但这对我不起作用.在阅读了节点的http文档之后,我也不再聪明: https://nodejs.org/api/http.html .

But I struggle. I tried req.on("close"..) and the on-finished npm module, but that didn't work for me. I'm also not much more clever after reading the http documentation of node: https://nodejs.org/api/http.html.

任何想法如何解决这只野兽?还是删除侦听器以防止内存泄漏的更好方法?

Any ideas how to tackle this beast? Or better ways to remove listeners to prevent memory leaks?

服务器端要领:

// server.js
var express = require("express");
var EventEmitter = require("events").EventEmitter;
var messageBus = new EventEmitter();
messageBus.setMaxListeners(20);

var REST_PORT = (process.env.PORT || 5000);
var app = express();

app.get("/events", (req, res) => {
    var listener = function(res) {
        messageBus.once("message", function(data) {
            res.status(200).json(data);
        });
    };
    req.on("abort", function() { //I tried also "aborted", "close", "closed", "finish", "finished"..no luck
        messageBus.removeListener("message", listener);
    });

    listener(res);
    console.log("Total listeners to 'message' events:", messageBus.listeners("message").length);
});

// other messageBus.emit logic ..

app.listen(REST_PORT, () => {
    console.log("Application ready on port " + REST_PORT);
});

客户端要领:

//client.js
$.ajax({
    method: "GET",
    async: true,
    url: "/events",
    success: function(data) {
        callback(data);
    },
    complete: function(request, status, err) {
        if (status == "timeout" || status == "success") {
            console.log("LOG: Normal long-polling timeout or successful poll, continuing.");
            longPoll();
        } else {
            console.warn("WARN: Server probably offline, retrying in 2 sec.");
            setTimeout(function() {
                longPoll();
            }, 2000);
        }
    },
    timeout: 30000
});

谢谢!

推荐答案

如果这对某人有所帮助,我最终决定以不同的方式实现长轮询,并在超时后在服务器端终止客户端请求.这对我来说很好,经过深思熟虑,这可能是一种比信任客户端正确关闭请求更好的机制.

If this helps someone, I finally decided to implement the long-polling differently and killing the client request at the server side after certain timeout. This works for me nicely and after reflection, is probably better mechanism than trusting the client to close the requests correctly.

setTimeout(() => {
    if (!responded) {
        messageBus.removeListener("message", listener);
        res.status(204).end();
    }
}, 30000);

这篇关于Node.js:使用EventEmitter和Express 4.x进行长轮询捕获请求关闭的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆