RemoveListener移除在“this”侦听器之后启动的所有侦听器

我有一个socket.io服务器,在每个socket.io连接中都有一个自定义的方法'looper.output'。 每当我closures一个socket.io连接,我启动另一个自定义方法“looper.disconnect”,应该删除closures客户端的“输出”侦听器。 我的问题是,无论何时closures客户端,looper.disconnect不仅从该客户端中删除侦听器,还会从closures客户端后启动的每个客户端中删除侦听器。

例如,如果我有4个客户端A,B,C和D,也按该顺序连接到服务器,并closures客户端C; looper.disconnect将删除C和D的侦听器,但只保留A和B.

我需要改变什么来使looper.disconnect只删除调用它的客户端的侦听器? 在上面的例子中,我只想要删除客户端C的侦听器。

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.output.outCallback = function(mydata) { return callback(mydata.trim()); } this.on('output', this.output.outCallback); } Looper.prototype.disconnect = function() { this.removeListener('output',this.output.outCallback); } 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.id); }); webSocket.on('disconnect', function() { looper.disconnect(); }); }); 

您可以将侦听器始终打开,并在侦听器函数中将数据发送到添加到活套对象的所有callback。

session_id为每个客户端确定callback。

 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; Looper.prototype.outCallbacks = {}; EventEmitter.call(this); } sys.inherits(Looper, EventEmitter); Looper.prototype.callAllCallbacks = function(data) { for (var callback in this.outCallbacks) { if (this.outCallbacks.hasOwnProperty(callback)) { this.outCallbacks[callback](data); } } } 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); }); this.on('output', this.callAllCallbacks); } Looper.prototype.addCallback = function(session_id, callback) { this.outCallbacks[session_id] = function(mydata) { return callback(mydata.trim()); } } Looper.prototype.disconnect = function(session_id) { delete this.outCallbacks[session_id]; } 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) { var session_id = webSocket.id; looper.addCallback(session_id, function(res) { webSocket.emit('stream',res+":"+webSocket.id); }); webSocket.on('disconnect', function() { looper.disconnect(session_id); }); }); 

我不明白为什么它会失败,但是你的主要问题是你在同一个地方保存了所有function的参考。

另一种select是为每个客户端提供一个callback函数参考,如下所示:

 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', callback); } Looper.prototype.disconnect = function(callback) { this.removeListener('output', callback); } 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) { var callback = function(res) { webSocket.emit('stream',res.trim()+":"+webSocket.id); } looper.output(callback); webSocket.on('disconnect', function() { looper.disconnect(callback); }); });