0

Express.js Web アプリで socket.io を使用して、SQL クエリを呼び出すイベントをリッスンしているクライアントのソケットを開きます。サーバーソケットは次のようになります。

socket.on('updates', function(PEMSID){
        setInterval(function(){
            gps_helper.get_gps(PEMSID, function(data){      //query GPS table for marker coordinates
                socket.emit('message', {message: data});
            });
        }, 10000);

get_gps()そのため、新しいレコードがテーブルに追加されたかどうかを確認するために長いポーリングを行う関数が10 秒ごとに呼び出されます。関数は次のget_gps()ようになります。

exports.get_gps = function(PEMSID, callback) {
    var sql = require('msnodesql');
    var connStr = "Driver={SQL Server Native Client 11.0};Server=myHost,1433;Database=myDB;UID=Username;PWD=Password;";
    var mQuery = "EXEC Z_CoordsByPEMS '" + PEMSID + "'";
    sql.open(connStr, function(err,conn){
        if(err)
            return console.error("Could not connect to sql: ", err);
        conn.query(mQuery,function(err,results){
            if (err)
                return console.error("Error running query: ", err);
            callback(results);  //return query results
        });
    });
}

私が遭遇している問題は、get_gps()更新をポーリングするたびに SQL データベースへの新しい接続を開いていることです。サーバーの CPU が最終的に最大容量に達し、今後のすべてのクエリがタイムアウトするため、これは明らかにデータベースをホストするサーバーに非常識なオーバーヘッドを引き起こし、変更する必要があります。モジュールを使用して SQL db タスクを実行していますが、API に既存の接続を閉じる関数msnodesqlがないようです。close()1 つのグローバル接続を作成し、すべての新しいソケットがロング ポーリングを行うためにそれを参照する必要があると思います。ただし、Express.js/node.js の非同期の性質を考えると、グローバル接続を設定する方法は、可能であればわかりません。

4

1 に答える 1

3

現在、送信するクエリごとに新しい SQL 接続を作成しています。代わりに、socket.io 接続ごとに 1 つの SQL 接続が必要だと言いました。リクエストを受け取るたびに SQL 接続を作成しますupdates(socket.io 接続ごとに 1 回だけこのメッセージを受け取ると仮定します)。

socket.on('updates', function(PEMSID){
    var sql = require('msnodesql');

    // open a new socket for each `updates` message
    sql.open(connStr, function(err,conn){
        if(err) { return console.error("Could not connect to sql: ", err); }

        // when the connection is made, start the interval
        setInterval(function(){

            // each interval, get_gps, and pass `conn` as an argument
            gps_helper.get_gps(conn, PEMSID, function(data){      //query GPS table for marker coordinates
                socket.emit('message', {message: data});
            });
        }, 10000);
    });
});

次に、関数は引数get_gpsを受け入れます。conn

exports.get_gps = function(conn, PEMSID, callback) {
    var connStr = "Driver={SQL Server Native Client 11.0};Server=myHost,1433;Database=myDB;UID=Username;PWD=Password;";
    var mQuery = "EXEC Z_CoordsByPEMS '" + PEMSID + "'";

    // no need to open `conn`; it's already made
    conn.query(mQuery,function(err,results){
        if (err)
            return console.error("Error running query: ", err);
        callback(results);  //return query results
    });
}

1 つのグローバル SQL 接続が必要な場合は、sql.open呼び出しをさらに高くするだけです。

// create conn outside of the socket.io message callback
sql.open(connStr, function(err,conn){
    if(err) { return console.error("Could not connect to sql: ", err); }

    io.sockets.on("connection", function(socket) {

        socket.on('updates', function(PEMSID){
            setInterval(function(){
                gps_helper.get_gps(conn, PEMSID, function(data){      //query GPS table for marker coordinates
                    socket.emit('message', {message: data});
                });
            }, 10000);
        });

    });
});
于 2013-11-05T14:03:57.613 に答える