2011-05-01 3 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/'); 

콘솔 로그는 모든 아약스 요청에 대한 두 개의 '등록'요청을 보여주는되고 난 쿼리가 발생한 얻을 곳에서 확실하지 않다 :

// 등록? = 1304280004069
// 등록 하시겠습니까? (HTML 본문에 위치)
= 1304280004068

클라이언트의 Ajax 호출 : 마지막으로

$(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를 클라이언트 요청으로 사용한다고 가정합니다. 캐시 ~ 으로 설정하면 jQuery가 각 요청에 고유 한 쿼리 문자열을 추가하여 새 데이터를 얻게됩니다.

AJAX 호출에서 doSomethingWithData 메서드를 이동하여 읽기 쉽도록 만들 수도 있습니다.

$(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

+0

** Math.random() **을 사용하여 **/Register ** 호출에 사용자 임의의 쿼리 문자열을 추가하는 방법 POST 요청을 대신 사용 하시겠습니까? 전의. url = "/ Register?" + Math.floor (Math.random() * 1e16); – Dan

+0

좋아, 내가 그냥 '?' 요청을 듣기 시작하도록합니다 (임의의 int가 필요 없음). 이제 중복없이 작업하고 있습니다! :) 그러나, 페이지는 끊임없이 "로딩"을 보여줍니다 ..이 Ajax 요청이 백그라운드에 있지 않아야합니까 ?? – yajus