2013-03-16 81 views
4

我目前正在尋找關於使用NodeJS和MySQL數據庫推送通知的解決方案。NodeJS + MySQL + Socket.IO:更新數據庫

我想結合NodeJS和Socket.IO來提供推送通知,但問題是我不知道如何讓我的服務器檢查是否有從我的數據庫更新。

我已經有一個完美的「輪詢」方法,但它有點混亂,而且在服務器調用和響應方面並沒有真正優化。

所以這個想法是,當用戶A在我的數據庫中插入一些東西時,所有跟隨他的客戶端都會通過push(push,not poll)得到通知。

這是我已經得到的時刻對我的server.js:

var app     = require('http').createServer(handler), 
    io     = require('socket.io').listen(app), 
    fs     = require('fs'), 
    mysql    = require('mysql'), 
    connectionsArray = [], 
    connection   = mysql.createConnection({ 
     host  : 'localhost', 
     user  : 'root', 
     password : 'root', 
     database : 'nodejs' 
    }), 
    POLLING_INTERVAL = 5000, 
    pollingTimer; 
connection.connect(function(err) { 
    console.log(err); 
}); 
app.listen(1337); 
function handler (req, res) { 
    fs.readFile(__dirname + '/client.html' , function (err, data) { 
     if (err) { 
      console.log(err); 
      res.writeHead(500); 
      return res.end('Error loading client.html'); 
     } 
     res.writeHead(200); 
     res.end(data); 
    }); 
} 
var pollingLoop = function() { 
    var query = connection.query('SELECT notif FROM notifications WHERE id_user=1 AND status=0'), 
     users = []; 
    .on('error', function(err) { 
     console.log(err); 
     updateSockets(err); 
    }) 
    .on('result', function(user) { 
     users.push(user); 
    }) 
    .on('end',function(){ 
     if(connectionsArray.length) { 
      pollingTimer = setTimeout(pollingLoop, POLLING_INTERVAL); 
      updateSockets({users:users}); 
     } 
    }); 
}; 
io.sockets.on('connection', function (socket) { 
    console.log('Number of connections:' + connectionsArray.length); 
    if (!connectionsArray.length) { 
     pollingLoop(); 
    } 
    socket.on('disconnect', function() { 
     var socketIndex = connectionsArray.indexOf(socket); 
     console.log('socket = ' + socketIndex + ' disconnected'); 
     if (socketIndex >= 0) { 
      connectionsArray.splice(socketIndex, 1); 
     } 
    }); 
    console.log('A new socket is connected!'); 
    connectionsArray.push(socket); 
}); 
var updateSockets = function (data) { 
    data.time = new Date(); 
    connectionsArray.forEach(function(tmpSocket){ 
     tmpSocket.volatile.emit('notification' , data); 
    }); 
}; 

如果您有任何意見,解決方案或東西,可以是有用的,不要猶豫。

在此先感謝

回答

3

我可以在這裏想到兩個解決方案。

1)從上傳新信息的相同請求開始推送。我這裏的意思是,你的流量,現在大概是:從客戶

  1. Get請求
  2. 插入內容DB
  3. 返回到客戶端

與節點以後還可以做更多的東西該響應已發送。對於來自客戶端 2.將東西例如 1 Get請求到DB 3.返回到客戶端 4.找出誰是訂閱和電流的所有用戶在 5.發送簽名推

2)這種做法是更分散式。您可以使用發佈/訂閱方法進行最後的步驟。有一個不同的進程處理所有推送,並讓您的主進程(處理更新請求的部分)將新內容發佈到隊列中。這會在每次有新內容時提醒您的推送過程,這比查詢數據庫要好得多。

注意,對於這兩種解決方案,你將不得不尋找跟蹤其中的插座連接到客戶的好方法,讓你快速地從插座外將消息發送到特定的客戶端。這樣做的一個快速方法可能是將每個用戶添加到他們自己的房間(以其用戶名或user_id命名),以便您可以輕鬆地將更新推送到以訂閱用戶命名的房間的所有參與者。如果沒有人在房間內,則不會發送請求。

+0

感謝您的解決方案。我要檢查他們兩人,看看哪一個會更有效率!我認爲我的輪詢版本完美工作(不是很難),但使用NodeJS進行輪詢有點「巨大」(我可以在沒有NodeJS的情況下進行輪詢)。如果我提供解決方案,我會在這裏發佈給大家。再次感謝 – Simon 2013-03-16 21:55:12

+1

第二種解決方案與查詢數據庫類似,但是您的應用程序基本上會說「嘿,現在有些新東西了!」,而不是一直問「嘿,你還有什麼嗎?」 – 2013-03-16 22:04:43