2011-05-01 77 views
1

我是新来的node.js,很难掌握事件监听器/发射器的动态。我正在尝试为典型的“新闻源”应用设置一个简单的长轮询监听器。我可以使用下面的代码注册并向侦听器发送事件。我的问题是,每次发生事件时,都会将其推送到客户端多次(两次或更多次)。Node.js重复听众问题

var http = require('http'), 
events = require('events'), 
url = require('url'); 

var event_emitter = new events.EventEmitter(); 

http.createServer(function(req,res) { 
var uriParse = url.parse(req.url,true); 
var pathname = uriParse.pathname; 
console.log(req.url); 
if (pathname=="//register") { 
    var thisRes = res; 
    event_emitter.addListener('event',function(actionid){ 
     if (thisRes) { 
     thisRes.writeHead(200, { "Content-Type": "text/plain" }); 
      thisRes.end(actionid); 
      thisRes = null; 
     } 
    }); 
} else if (pathname=="//emit") { 
    var actionid = uriParse.query.id; 
    event_emitter.emit('event',actionid); 
    console.log('event',actionid); 
    res.writeHead(200, { "Content-Type": "text/plain" }); 
    res.end('success'); 
} 

}).listen(3000,"127.0.0.1"); 
console.log('Server running at http://127.0.0.1:3000/'); 

控制台日志中显示为每个Ajax请求两个“注册”请求,我不是从一开始查询来源于哪里肯定:

//注册? = 1304280004069
//注册?
= 1304280004068

客户端的Ajax调用(位于HTML内):

$(document).ready(function() { 
    function callNode() { 
     $.ajax({ 
      url: '/node/register', 
      cache: false, 
      timeout: 100000 * 1000000, 
      success: function(data) { 
       function doSomethingWithData(newaction) { 
        $('#feed').prepend(newaction); 
       } 
       $.get('/news/'+ data+'/', doSomethingWithData); 
       callNode(); 
      } 
     }); 
    }; 
    callNode(); 
}); 

最后,另一个问题是,Ajax调用没有在后台发生,但页面显示为“加载“直到第一个节点发射(之后它在后台静静地运行)。感谢您的任何建议。

回答

2

我假设你使用jQuery作为客户端请求。它看起来像设置缓存false,jQuery正在添加一个唯一的查询字符串到每个请求,以确保您获得新的数据。

您可能还想将doSomethingWithData方法从您的AJAX调用中移出,以使其更易于阅读。

$(document).ready(function() { 
    function doSomethingWithData(newaction) { 
     $('#feed').prepend(newaction); 
    } 

    (function callNode() { 
     $.ajax({ 
      url: '/node/register', 
      cache: false, 
      timeout: 100000 * 1000000, 
      success: function(data) { 
       $.get('/news/'+ data+'/', doSomethingWithData); 
       callNode(); 
      } 
     }); 
    }()); 
}); 
+0

那么,这解决了查询字符串的奥秘。但是,将缓存更改为true将导致没有侦听器被注册(而不是2+)。 – yajus 2011-05-01 20:36:53

+0

如何使用** Math.random()**将自定义随机查询字符串添加到您的**/Register **调用或使用POST请求呢?防爆。 url =“/注册?” + Math.floor(Math.random()* 1e16); – Dan 2011-05-01 20:47:43

+0

好的,事实证明我只需要追加'?'使请求开始监听(不需要随机int)。现在它没有重复的工作! :)但是,页面显示不断“加载”..不应该这个Ajax请求在后台? – yajus 2011-05-01 20:55:20