我的听众有问题。我在自己开发的节点中的http侦听器中有多个输入。我用过这样的东西:
...
server.on(‘connection’, function(){
node.on(‘input’, function(){
// something to manage messages
});
});
...
我想选择何时停止监听器(例如,当它找到特定的msg.payload时)。我尝试了“node.once(..”,“node.removeListener(..”但没有。你能帮助我吗?谢谢。
修改
所有代码:
var server = http.createServer((request, response) => {
if (request.url == '/log' || request.url == '/log2'){
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
response.on('error', (err) => {
console.error(err);
});
response.statusCode = 200;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Content-Type", "text/html");
msg = {_msgid:"1c6db704.811319", topic:request.url ,payload: true};
node.send(msg);
function inputListener(msg) {
console.log(msg.topic + " " + request.url);
if (msg.topic == request.url)
response.end(JSON.stringify(msg.payload));
//node.removeListener('input', inputListener);
}
node.on('input', inputListener);
});
} else {
response.statusCode = 404;
response.end();
}
}).listen(8088);
编辑2
似乎可以使用这个技巧:
function inputListener(msg) {
if (msg.topic == request.url)
response.end(JSON.stringify(msg.payload));
else
node.once('input', inputListener);
}
node.once('input', inputListener);
答案 0 :(得分:1)
node.removeListener()
如果您正确使用它将会正常工作,所以我假设您没有正确使用它。要正确使用.removeListener()
删除一个特定的侦听器,您必须将最初侦听的消息和相同的函数引用传递给它。这意味着你不能使用像你所示的匿名函数引用:
相反,你可以这样做:
server.on('connection', function(){
function inputListener(data) {
// something to manage messages
if (someCondition) {
// if some condition is met, then remove this specific listener
node.removeListener('input', inputListener);
}
}
node.on('input', inputListener);
});
这里代码创建了一个本地函数(每次调用connection
处理程序时它都是唯一的),然后将其与.on()
一起使用。然后,当您要删除该特定侦听器时,允许您将完全相同的函数引用传递给.removeListener()
。值得回顾doc for .removeListener()
。
node.once()
也有自己的特定目的。它的作用是在下次事件触发后自动删除事件监听器。如果这正是您想要的情况,那将非常方便。但是,如果您想测试某些条件并且仅在满足条件时删除事件处理程序,并且有时需要查看事件的多次出现,那么您就不能使用.once()
。
P.S。您的问题包含您的活动名称的非法类型的引号。这在Javascript中不起作用。您永远不应该在执行该类处理的文字处理器中编辑代码。始终使用文本编辑器。
既然您已经包含了更多真实代码,那么您似乎遇到了并发问题,因为您为所有请求使用了相同的node
对象,因此您无法使用告诉哪个input
事件属于哪个请求。您需要解决该问题。
有很多方法可以做到,但这是一种方法。您需要更改node
对象,以便它接收您发送的唯一ID,并将其与响应一起返回,以便您可以确定哪个响应与哪个请求相关。
const unique = require('node-unique');
var server = http.createServer((request, response) => {
if (request.url == '/log' || request.url == '/log2'){
let body = [];
request.on('error', (err) => {
console.error(err);
}).on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
response.on('error', (err) => {
console.error(err);
});
response.statusCode = 200;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Content-Type", "text/html");
// generate unique id for this request
let uniqueID = unique();
msg = {_msgid:"1c6db704.811319", topic:request.url ,payload: true, id: uniqueID};
node.send(msg);
function inputListener(msg) {
// ignore if this is not our msg
if (msg.id === uniqueID) {
console.log(msg.topic + " " + request.url);
if (msg.topic == request.url)
response.end(JSON.stringify(msg.payload));
node.removeListener('input', inputListener);
}
}
node.on('input', inputListener);
});
} else {
response.statusCode = 404;
response.end();
}
}).listen(8088);