简体   繁体   中英

EventEmitter memory leak from function within socket.io handler

I have a server that requires a dynamic value that's continuously updating from a spawned process. I tried to make a custom listener outside of the scope of the server because I was receiving potential memory leaks errors but I'm still receiving these messages after several connect/disconnects occur on the server. Why arn't the listeners that were added after the initial connect being removed during the disconnect event listener?

var express = require('express');
var http = require('http');
var spawn = require('child_process').spawn;
var util = require('util');
var fs = require('fs');
var EventEmitter = require('events').EventEmitter;
var sys = require('sys');

var app     = express(),
    server  = http.createServer(app),
    io      = require('socket.io').listen(server);

function Looper(req)  {
    this.req = req;
    EventEmitter.call(this);
}
sys.inherits(Looper, EventEmitter);

Looper.prototype.run = function() {
    var self = this;
    var cmd = spawn('./flow',[this.req]); // <-- script that outputs req every second
    cmd.stdout.setEncoding('utf8');
    cmd.stdout.on('data', function(data) {
        self.emit('output',data);
    });
}

Looper.prototype.output = function(callback) {
    this.on('output', function(data) {
        return callback(data.trim());
    });
}

var looper = new Looper('blah');
looper.run();

app.use(express.static(__dirname + '/public'));

app.get('/', function(req, res) {
    res.send(
        "<script src='/socket.io/socket.io.js'></script>\n"+
        "<script>\n"+
        "\tvar socket=io.connect('http://127.0.0.1:3000');\n"+
        "\tsocket.on('stream', function(data) {\n"+
        "\t\tconsole.log(data);\n"+
        "\t});\n"+
        "</script>\n"
    );
});
server.listen(3000);

io.sockets.on('connection', function(webSocket) {
    looper.output(function(res) {
        webSocket.emit('stream',res);
    });

    webSocket.on('disconnect', function() {
        looper.removeListener('output',looper.output); // <- not remove listener added when connection was made
    });
});

You add(!) an extra callback function every time you call looper.output to the event 'output'. I don't know what you want to achieve, but to get this call only once use this.once('output', ...) or move the callback setting to the object or remove the old function first...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM