如何每个Web套接字只使用一个DB连接?

时间:2013-11-05 13:38:50

标签: javascript node.js express socket.io

我在Express.js网络应用程序中使用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()函数进行长轮询以检查是否有任何新记录添加到表中。 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 db的新连接。这显然会导致托管数据库的服务器出现疯狂的开销,需要更改,因为服务器的CPU最终达到最大容量,所有未来的查询都会超时。我正在使用模块msnodesql来执行SQL db任务,但它没有出现在API中有close()函数来关闭现有连接。我想我需要创建一个全局连接,然后让所有新的套接字引用它们以进行长轮询。鉴于Express.js / node.js的异步特性,我不确定如何设置全局连接,如果可能的话。

1 个答案:

答案 0 :(得分:3)

目前,您正在为发送的每个查询创建新的SQL连接。相反,您已经说过要为每个socket.io连接建立一个SQL连接。每当收到updates请求时创建SQL连接(假设每个socket.io连接只收到一次此消息):

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
    });
}

如果您想要一个全局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);
        });

    });
});