我在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的异步特性,我不确定如何设置全局连接,如果可能的话。
答案 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);
});
});
});