2013-07-16 10 views
2

我得到了一個RubyOnRails應用程序,它使用Node.js/Socket.io服務器將交易信息推送到所有連接的客戶端。無論何時執行交易,客戶端屏幕都會根據上次交易的信息進行更新。如何使用Redis/Node/Rails延遲和合並pub/sub

隨着交易頻率的增加,每隔一秒甚至更頻繁發生一次更新就會變得相當煩人。我正在尋找一種方法來處理僅將最新更新推送到客戶端。每5秒一次,即如果沒有交易發生,則不會推送任何東西。

我至今是: 我通過從Rails應用程序推交易信息,以Redis的:

REDIS.publish('tradeupdate', .....) 

和節點服務器確實是這樣的:

cli_sub.subscribe("tradeupdate"); 
cli_sub.on("message",function(channel,message) { 
    io.sockets.emit('ablv', message); 
}); 

和客戶端那麼

socket.on('ablv', function (data) { 
    obj = JSON.parse(data); 
    ..... 
}); 

目標是隻有最後一條消息w在給定的時期(例如, 5秒)從Rails發送到Node或從Node發送到客戶端。

+0

爲什麼這是一個downvote? – KKK

+0

這是用於Vircurex還是Cryptostocks? – apscience

+0

Vircurex,一旦節流和Chrome內存泄漏問題得到解決。 – KKK

回答

1

它看起來像你在這裏需要的是一個助手,用於限制你的函數調用。例如:

var makeThrottler = function() { 
    var toRun = null, timeout = null; 

    function doRun() { 
     if (!toRun) { 
      // nothing to run; we set timeout to null so that the 
      // next function to execute knows to run immediately 
      timeout = null; 
      return; 
     } 

     // set a timeout of 5s before 
     timeout = setTimeout(function() { 
      doRun(); 
     }, 5000); 

     // we need to do this temp thing to protect against 
     // calling executeThrottled again within toRun 
     var temp = toRun; 
     toRun = null; 
     temp(); 
    } 

    function executeThrottled(fn) { 
     // this is the function we want to execute next; it 
     // overwrites any function we've stored earlier 
     toRun = fn; 

     // if we already ran within the last 5 seconds, don't do 
     // anything now (our function will be called later) 
     if (timeout) 
      return; 

     // execute the function right away 
     doRun(); 
    } 

    return executeThrottled; 
} 

這裏有一個如何使用它的一個例子:

var throttled = makeThrottler(), x = 0; 
function increment() { 
    throttled(function() { 
     console.log(x); 
    }); 
    x++; 
    setTimeout(increment, 1000); 
} 
increment(); 

增量功能通過一個每秒增加x。該日誌被節流,所以你會看到輸出爲0,5,10等(它們可能會不定期關閉的一個,因爲輕微的計時不準確的。)

你原來的代碼將成爲類似:

cli_sub.subscribe("tradeupdate"); 
cli_sub.on("message",function(channel,message) { 
    throttled(function() { 
     io.sockets.emit('ablv', message); 
    }); 
}); 
2

什麼阻止你緩衝消息,並使用一個簡單的計時器來每五秒執行一次發射?

var last_message = null; 

cli_sub.subscribe("tradeupdate"); 
cli_sub.on("message",function(channel,message) { 
    last_message = message; 
}); 

setInterval(function() { 
    io.sockets.emit('ablv', last_message); 
}, 5000); 
+0

這會產生幾秒的額外延遲。我不確定這對於@庫馬拉很重要。 – arghbleargh