Node.js:这个长轮询实现是否泄漏:

我正在评估Node.js,以便在Java Web App上replace当前的推送function。 我写了一个简单的长轮询服务器,就像客户端和Java后端之间的中介一样工作。 客户端发出请求订阅,然后Java服务器可以通过调用Node.js来通知订阅的客户端。 目前为止似乎工作正常,但我得到了以下消息指出内存泄漏:

(node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. Trace at EventEmitter.addListener (events.js:168:15) at EventEmitter.once (events.js:189:8) at route (C:\Users\Juan Pablo\pushserver.js:42:12) at Server.onRequest (C:\Users\Juan Pablo\pushserver.js:32:3) at Server.EventEmitter.emit (events.js:91:17) at HTTPParser.parser.onIncoming (http.js:1793:12) at HTTPParser.parserOnHeadersComplete [as onHeadersComplete] (http.js:111:23 ) at Socket.socket.ondata (http.js:1690:22) at TCP.onread (net.js:402:27) 

我有一行代码logging现有的侦听器,每当一个通知事件发射。 我已经运行了一段时间,它显示每个订阅客户端只有一个监听器(应该是这样),但是当我收到警告消息时,这行代码不在代码中。 代码是完全一样的,除了那条线艰难。

这是推送服务器的代码(因为我还在学习Node.js,所以这个代码很简单):

 var http = require('http'); var url = require("url"); var qs = require("querystring"); var events = require('events'); var util = require('util'); var emitter = new events.EventEmitter; function onRequest(request, response) { var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); request.setEncoding("utf8"); if (request.method == 'POST') { var postData = ""; request.addListener("data", function(postDataChunk) { postData += postDataChunk; console.log("Received POST data chunk '"+ postDataChunk + "'."); }); request.addListener("end", function() { route(pathname, response, postData); }); } else if (request.method=='GET') { var urlParts = url.parse(request.url, true); route(pathname, response, urlParts.query); } } function route(pathname, response, data) { switch (pathname) { case "/subscription": emitter.once("event:notify", function(ids) { response.writeHead(200, {"Content-Type": "text/html", "Access-Control-Allow-Origin": "*"}); response.write(JSON.stringify(ids)); response.end(); }); break; case "/notification": //show how many listeners exist console.log(util.inspect(emitter.listeners('event:notify')); emitter.emit("event:notify", data.ids); response.writeHead(200, {"Content-Type": "text/html", "Access-Control-Allow-Origin": "*"}); response.write(JSON.stringify(true)); response.end(); break; default: console.log("No request handler found for " + pathname); response.writeHead(404, {"Content-Type": "text/plain", "Access-Control-Allow-Origin": "*"}); response.write("404 - Not found"); response.end(); break; } } http.createServer(onRequest).listen(8888); console.log('Server running at http://127.0.0.1:8888/'); 

我的印象是,使用emitter.once会自动删除事件监听器,所以我不知道如果只有一个客户端连接,如何添加11个监听器。 我在想,也许如果客户端在等待通知时断开连接,那么关联的连接资源就不会被处置。

我想知道是否需要手动处理断开连接,以及是否有泄漏。 任何build议是受欢迎的。 谢谢。

如果有人感兴趣,上面的代码确实泄漏。 在发送通知之前客户端断开连接时发生泄漏。 为了解决这个问题,有必要在客户端突然中断时删除事件监听器,比如:

 case "/subscription": var notify = function(ids) { response.writeHead(200, {"Content-Type": "text/html", "Access-Control-Allow-Origin": "*"}); response.write(JSON.stringify(ids)); response.end(); } emitter.once("event:notify", notify); //event will be removed when connection is closed request.on("close", function() { emitter.removeListener("event:notify", notify); }); break;