Node.js:使用EventEmitter和Express 4.x进行长轮询 捕获请求关闭

我使用JQuery的ajax请求(xhr)进行long-polling node.js路由。 这会向我的Express服务器发送GET请求并侦听消息总线事件。 我在该GET请求上设置了超时(因为我的代理会终止长请求)。 因此,在超时后,客户端应该将中止事件发送到服务器。

我想捕获中止/关闭/结束事件并删除相关的消息总线侦听器/订阅者。

但我很挣扎。 我尝试了req.on(“关闭”..)和完成的npm模块,但这对我不起作用。 阅读节点的http文档后,我也没那么聪明了: https : //nodejs.org/api/http.html 。

任何想法如何解决这个野兽? 或者更好的方法来删除侦听器以防止内存泄漏?

服务器端要领:

// 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 }); 

谢谢!

我建议完全中止自定义长轮询系统并使用现有的消息传递/套接字类型系统之一。 有许多是完全形成的。 socket.io是最受欢迎的,并且效果很好,但是这些替代品可能会更好一些https://www.reddit.com/r/node/comments/4ktqae/socketio_alternatives/

如果这对某人有帮助,我最终决定以不同的方式实现长轮询并在特定超时后在服务器端终止客户端请求。 这很适合我,反思后,可能是比信任客户端正确关闭请求更好的机制。

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