5

現在、NodeJS と MySQL データベースを使用したプッシュ通知に関するソリューションを探しています。

NodeJS と Socket.IO を組み合わせてプッシュ通知を提供したいのですが、データベースからの更新があるかどうかをサーバーに確認する方法がわからないという問題があります。

私はすでに完全に機能する「ポーリング」メソッドを持っていますが、少し面倒で、サーバーの呼び出しと応答に関しては実際には最適化されていません。

つまり、ユーザー A が私のデータベースに何かを挿入すると、彼をフォローしているすべてのクライアントがプッシュ (ポーリングではなくプッシュ) によって通知されるという考えです。

これは私が 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 );
    });
};

アドバイス、解決策、または役立つ可能性があるものがあれば、躊躇しないでください。

前もって感謝します

4

1 に答える 1

5

ここで2つの解決策を考えることができます。

1) 新しい情報をアップロードしたのと同じリクエストからプッシュを開始します。ここで言いたいのは、今のあなたの流れはおそらく次のようなものだということです:

  1. クライアントからリクエストを取得
  2. DBに物を挿入する
  3. クライアントに戻る

Node を使用すると、応答が送信された後にさらに多くのことを実行できます。たとえば、1. クライアントからリクエストを取得する 2. DB にデータを挿入する 3. クライアントに戻る 4. サブスクライブして現在サインインしているすべてのサブスクライバーを検索する 5. プッシュを送信する

2) このアプローチはより分散されています。最後の手順では、pub/sub メソッドを使用できます。別のプロセスですべてのプッシュを処理し、メイン プロセス (更新要求を処理する部分) で新しいコンテンツをキューに発行します。これにより、新しいコンテンツが存在するたびにプッシュ プロセスが警告されるため、データベースをポーリングするよりもはるかに優れています。

これらの解決策のいずれについても、どのソケットがどのクライアントに接続されているかを追跡する適切な方法を見つける必要があることに注意してください。これにより、ソケットの外部から特定のクライアントにメッセージをすばやく送信できます。これを行う簡単な方法は、各ユーザーをユーザー名または user_id にちなんで名付けられた独自のルームに追加することです。これにより、購読しているユーザーにちなんで名付けられたルームのすべての参加者に更新を簡単にプッシュできます。ルームに誰もいない場合、リクエストは送信されません。

于 2013-03-16T21:33:17.777 に答える