I am using socket.io in my Express.js web app to open sockets for clients that are listening for events that call a SQL query. The server socket looks like this:
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);
So, every ten second the get_gps() function is being called that does long polling to check if any new records have been added to a table. The get_gps() function looks like this:
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
});
});
}
The problem I'm encountering is the get_gps() is opening a new connection to the SQL db everytime it polls for any updates. This is obviouslly causing insane overhead on the server hosting the db and needs to be changed, as the server's CPU eventually reaches maximum capacity and all future queries time out. I'm using the module msnodesql to do the SQL db tasks, but it doesn't appear there's a close() function in the API to close existing connections. I think I'll need to create one global connection and then have all new sockets reference that in order to do their long polling. I'm unsure however how to set up the global connection, if it's even possible, given the asynchronous nature of Express.js/node.js.
sql.opencall into youron('updates', ...)handler and pass theconnobject as an argument intoget_gps. If you want one connection globally, do the same thing, but move thesql.opento the top of your code and place all your other code inside the connection callback.