2013-03-16 3 views
4

Я в настоящее время ищу решение о push-уведомлениях с помощью NodeJS и базы данных MySQL.NodeJS + MySQL + Socket.IO: обновить базу данных

Я хочу объединить NodeJS с Socket.IO для предоставления push-уведомлений, но проблема в том, что я не знаю, как попросить мой сервер проверить, есть ли обновление из моей базы данных.

У меня уже есть метод «опроса», который отлично работает, но он немного грязный, и это не очень оптимизируется с точки зрения вызовов и ответов сервера.

Итак, идея заключается в том, что когда пользователь А вставляет что-то в мою базу данных, все клиенты, которые следуют за ним, получают уведомление посредством 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. Получить запрос от клиента
  2. Вставьте материал в БД
  3. Вернуться к клиенту

С Node вы можете сделать больше материала после ответ был отправлен. Например 1. Получить запрос от клиента 2. Вставьте материал в БД 3. Возврат к клиенту 4. Найти все абоненты, которые подписываются и тока, подписанного в 5. Отправить выталкивает

2) Этот подход является более распределены. Вы можете использовать метод pub/sub для последних шагов. Имейте другой процесс обработки всех нажатий, и ваш основной процесс (часть, которая обрабатывает запросы на обновление) публикует новое содержимое в очередь. Это будет предупреждать ваш процесс нажатия каждый раз, когда появляется новый контент, что намного лучше, чем опрос вашей базы данных.

Обратите внимание, что для любого из этих решений вам нужно будет найти хороший способ отслеживания того, какие сокеты подключены к каким клиентам, чтобы вы могли быстро отправлять сообщения конкретному клиенту из своего сокета. Быстрый способ сделать это может заключаться в том, чтобы добавить каждого пользователя в свою собственную комнату, названную по имени пользователя или user_id, чтобы вы могли легко довести обновление до всех участников комнат, названных после подписки. Если никто не находится в комнате, запросы не отправляются.

+0

Спасибо за это решение. Я собираюсь проверить их обоих, чтобы увидеть, что один будет более эффективным! Думаю, что моя версия опроса работает отлично (не очень сложно), но использование NodeJS для опроса немного «огромно» (я могу делать опрос без NodeJS). Если я приду с решением, я собираюсь опубликовать его здесь для всех. Еще раз спасибо – Simon

+1

Второе решение похоже на опрос базы данных, однако ваше приложение в основном говорит: «Эй, сейчас для вас что-то новое!», вместо того чтобы вы постоянно спрашивали: «Эй, у вас есть что-нибудь для меня еще?» –

Смежные вопросы