2014-05-03 70 views
3

我一直在用socket.io和express來擺弄。我在這個項目中使用貓鼬。我有這樣的代碼:Node.js Socket.io和Express:不斷向setInterval方法以外的客戶端發送數據

服務器

io.on('connection', function (socket) { 
    setInterval(function(){ 
     Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) { 
      if (err) { 
       console.log(err); 
      } else { 
       socket.emit('data', {datas: data}); 
      }; 
     }) 
    }, 500); 
}); 

客戶

var socket = io.connect(); 
socket.on('data', function (data) { 
    if (data) { 
     $('#names').html(''); 
     $.each(data.datas, function (index, value) { 
      $('#names').append('<li>'+ value.name +'</li>') 
     }) 
    }; 
}); 

是否恰當的socket.io連接上執行的setInterval從數據庫加載必要的數據發送它不斷地給客戶?這會影響服務器的性能嗎?如果是這樣,那麼從mongodb向客戶端連續提取數據的最佳方式是什麼?如果有人從用戶/客戶端添加數據,是否有方法可以觀察(或類似數據庫觸發器)MongoDB中的集合?在我的代碼中,我是否正確地將mongodb查詢放入setInterval函數中?我是使用node.js,socket.io和mongodb的新手。有人能指引我走向正確的道路嗎?提前致謝!

回答

1

下面是我已經完成的,而不是使用setInterval方法,以防有人想知道我在項目中做了些什麼。由於@Mariusz評論

「怎麼樣通過誰寫 數據庫中的一個叫做簡單的HTTP web服務?」

給了我一個主意。相反,我所做的是在表單提交socket.emit('client_data', {'data': $(this).serializeArray()});的表單上添加事件點擊方法以將數據發送到服務器。然後在服務器上調用socket.on('client_data')方法從客戶端獲取數據以將其保存到數據庫,並從回調中調用io.sockets.emit方法以將更新後的數據發送回客戶端(reference on how to send responses to clients )。對不起,如果不能更好地解釋它,但這是代碼,所以你可以弄明白。

客戶

<script src="/js/jquery.min.js"></script> 
<script src="/socket.io/socket.io.js"></script> 
<form id="form" method="post"> 
    <label for="name">Name: <input id="text"type="text" name="name"></label> 
    <button id="submit" name="submit">save</button> 
</form> 
<ul id="names"> 
{% if datas %} 
    {% for data in datas %} 
    <li>{{data.name}}</li> 
    {% endfor %} 
{% else %} 
    <li>No data</li> 
{% endif %} 
</ul> 

<script> 
$(document).ready(function(){ 
    var socket = io.connect(); 
    socket.on('data', function (data) { 
     if (data) { 
      $('#names').html(''); 
      $.each(data.datas, function (index, value) { 
       $('#names').append('<li>'+ value.name +'</li>') 
      }) 
     }; 
    }); 

    $('#form').on('submit', function(e){ 
     e.preventDefault(); 
     socket.emit('client_data', {'data': $(this).serializeArray()}); 
     $('#text').val('').focus(); 
    }) 
}); 
</script> 

服務器

io.on('connection', function (socket) { 
    socket.on('client_data', function(data){ 
     Data.create({ 
      name: data.data[0].value 
     }, function (err, newData) { 
      console.log(newData.name + ' is now saved in the database.') 
      Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) { 
       if (err) { 
        console.log(err); 
       } else { 
        io.sockets.emit('data', {datas: data}); 
       }; 
      }) 
     }) 
    }); 
}); 

現在每次用戶/客戶端更新數據,所有的頁面也會被不使用的setInterval刷新數據更新。 希望它有幫助!

1

也許你最好用像RabbitMQ這樣的消息隊列解決方案?這樣您可以將消息從一個進程發送到另一個進程,並自動通知。我已經在使用Node.js,socket.io和RabbitMQ的應用程序中實現了通知(如果它接近您感興趣的區域)。這是一個開源項目,我會分享,如果你想(它在GitHub上,但變化尚未合併)。

在任何情況下,在這種情況下,事件總是比輪詢更好(如果可能的話)。

+0

感謝@Mariusz我爲RabbitMQ添加書籤以備將來之用。但是現在我需要知道使用socket.io的可能性。 –

+1

我不太瞭解MongoDB,但除非您在同一個Node.js應用程序中將數據添加到數據庫中,否則您將需要使用某種IPC解決方案。否則,你會變得效率低下,因爲數據庫命中應該通常最小化。如果沒有RabbitMQ,那麼寫入數據庫的人調用一個簡單的HTTP Web服務怎麼樣?這將做這項工作(儘管開銷會稍大)。 – Mariusz

+0

「如何寫入數據庫的人調用簡單的HTTP Web服務?」嗯,你給了我一個主意。讓我來研究一下。我對這個想法投了你的評論。 –

相關問題