I'm trying to connect to a remote database from my phonegap app.
I'm using an example script I found, but it's not working, as I keep getting require is not defined error.
Here's my code (it's inside a tag):
var Client = require('mysql').Client;
var client = new Client();
client.host ='1**.**.**.**8:****';
client.user = '*****';
client.password = '*****************';
console.log("connecting...");
client.connect(function(err, results) {
if (err) {
console.log("ERROR: " + err.message);
throw err;
}
console.log("connected.");
clientConnected(client);
});
clientConnected = function(client)
{
tableHasData(client);
}
tableHasData = function(client)
{
client.query(
'SELECT * FROM test_db.Users LIMIT 0,10',
// you can keep this function anonymous
function (err, results, fields) {
if (err) {
console.log("ERROR: " + err.message);
throw err;
}
console.log("Got "+results.length+" Rows:");
for(var i in results){
console.log(results[i]);
console.log('\n');
//console.log("The meta data about the columns:");
//console.log(fields);
}
client.end();
});
};
What am I doing wrong??
You are probably using nodeJS code that can't be run on Cordova. This must be run with node.
What you need to do is create a server (where you will run your code with nodeJS) and expose your data through an API for the client (your Cordova app) to come and fetch them. (Use AJAX requests)
Related
I have a MongoDB instance and two JavaScript services running on a Linux server. The first service, moscaService.js, listens to MQTT topics on the server, and records what is sent in a MongoDB collection. The second service, integrationService.js, runs every second, reading data on the same MongoDB collection and, if there's a new register (or more), sends it to Ubidots.
The problem is that both services work on the same IP/port: localhost:27017; and, if there ever is an occasion in which both of them are active simultaneously (say, moscaService.js is recording something and then the integrationService.js tries to connect), there will be a connection error and the service will restart.
Here are the connection parts of both services:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://127.0.0.1:27017/myGateway';
//integrationService.js
var job1 = new CronJob('*/1 * * * * *', function() {
MongoClient.connect(url, function(err, db) {
if(err != null) {
logger.error({message: 'Connection error: ' + err});
process.exit(0);
} else {
executeService();
}
function executeService() {
// execution block
}
});
}, null, true, timeZone);
//moscaService.js
server.on('published', function(packet, client) {
//the packet is read here
MongoClient.connect(url, function(err, db) {
if(err != null) {
logger.error({message: 'Connection error: ' + err});
process.exit(0);
} else {
executeService();
}
function executeService() {
// execution block
}
});
});
What I need is a way to properly handle the err instead of just exiting the service, because if there are new messages being published while the service is restarting, they will be lost. Something like testing if the port is open before connecting, or open a different port.
I tried creating another instance of MongoDB on a different port, in order to have each service listen to one, but it looks like Mongo locks more than one instance if it's trying to connect to the same database.
The code snippets here are just a small part; if anyone needs more parts to answer, just say so and I'll add them.
I have made an alteration and it solved this issue. I altered the code in a way that integrationService connects to MongoDB before starting the CronJob; that way, it only connects once and it keeps the connection alive.
Here's the connection part of the code:
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://127.0.0.1:27017/myGateway';
//integrationService.js
MongoClient.connect(url, function(err, db) {
var job1 = new CronJob('*/1 * * * * *', function() {
if(err != null) {
logger.error({message: 'Connection error: ' + err});
process.exit(0);
} else {
executeService();
}
function executeService() {
// execution block
}
}, null, true, timeZone); // end CronJob
}); // end MongoClient.connect
Since this has solved the problem, I've left the err treatment as is was (although a more elegant way to treat it is still desirable).
Solving the problem on integrationService has solved it on moscaService as well, but I plan to make the same alteration on the second service too.
I'm buidling an app with Node anb Mongodb Native. I'm working on a db module which i can require and call in other modules so that I end up using just one connection. The module db.js started out with this code:
var _db = null;
var getDb = module.exports.getDb = function(callback) {
if (_db) {
console.log('_db returned');
return callback(null, _db);
}
MongoClient.connect('mongodb://localhost:' + config.db.port + '/' + config.db.name, {native_parser: true}, function (err, db) {
if (err) return callback(err);
console.log('_db created');
_db = db;
callback(err, _db);
});
};
In my other modules that need a db connection I do this
db.getDb(function (err, connection) {
// Do something with connection
});
It works fine. But an unpleasant problem is that if my code would call getDb multiple times in a very short time span, I would end up with several copies of a connection. Like if I do my db.js requirements and getDb calls at the very beginning of all modules that need a db connection
I'm now thinking about controlling the calls to getDb by queuing them, so that only the absolute first call will create a connection and save it in _db. All later calls will get the created connection _db in return. I believe Async queue will help me with this...
The problem is that i dont understand how I write this with Async queue. The documentation is a little bit vague, and i dont find any better examples online. Maybe you can give me some hints. This is what i got so far...
var dbCalls = async.queue(function (task, callback) {
if (_db) {
console.log('_db returned');
return callback(null, _db);
}
MongoClient.connect('mongodb://localhost:' + config.db.port + '/' + config.db.name, {native_parser: true}, function (err, db) {
if (err) return callback(err);
console.log('Connected to mongodb://localhost:' + config.db.port + '/' + config.db.name);
_db = db;
callback(null, _db);
});
}, 1);
// I guess this .push() must be the exposed (exported) API for other modules to get a connection, but how do I return it to them,
dbCalls.push(null, function (err) {
console.log('finished processing foo');
});
dbCalls.push(null, function (err) {
console.log('finished processing bar');
});
I dont understand the object passed as first argument to .push() What should i use if for? Right now its null How do I pass on the connection and possible error all the way out to the module that made the call?
A quick and dirty solution without async.queue:
var _db = null;
var _err = null;
var _queue = [];
var _pending = false;
var getDb = module.exports.getDb = function(callback) {
if (_err || _db) {
console.log('_db returned');
return callback(_err, _db);
} else if (_pending) { // already a connect() request pending
_queue.push(callback);
} else {
_pending = true;
_queue.push(callback);
MongoClient.connect(..., function (err, db) {
_err = err;
_db = db;
_queue.forEach(function(queuedCallback) {
queuedCallback(err, db);
});
});
};
How can I fail a PULL to get retransmit from the pusher?
In the following example, if I uncomment the // throw ... to trigger an exception on every received message, all the PULL messages are failing, but when I put back the comment, all those messages are lost and not retransmitted by the pusher.
How can I make sure the pusher will retransmit the messages if the PULL method fail?
P.S. The following code is JavaScript in Meteor framework on top of nodejs, but it's not relevant to the problem as I suppose it's similar in every zmq implementations.
var zmq = Npm.require(modulePath + '/zmq');
var sock = zmq.socket('pull');
sock.identity = 'receiving' + process.pid;
sock.bind('tcp://172.17.4.25:5551', function(err) {
if (err) throw err
if (debug) console.log('Listening for ZMQ messages')
});
sock.on('message', Meteor.bindEnvironment(function(data) {
// throw { name: 'MessagePullFailed', message: 'Failing Pull message to check if ZMQ can recover from it' }
var jsondata = JSON.parse(data)
if (jsondata.cmd == 'upsert') {
jsondata['set']['utctime'] = new Date(jsondata['set']['utctime'])
Mon.upsert({_id: jsondata._id}, {'$set': jsondata['set']}, function(err) {
if (err) console.log(err)
})
}
}))
I am using Node JS with IIS (IISNode) and Microsoft's MS SQL driver package (MSNodeSQL) to create a http server. When accessing my database via the http server I get the following error when attempting to connect to the MS SQL database:
error { [Error: [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified] sqlstate: 'IM002', code: 0 }
But if I try to access the database locally on my server without the http server, then it connects perfectly fine. The ODBC driver is obviously installed.
Here is my code:
var http = require('http');
var sql = require('msnodesql');
var conn_str = "Driver={SQL Server Native Client 11.0}; Server=***; Database=***; UID=***; PWD=***;";
var blah = "";
http.createServer(function (req, res) {
sql.open(conn_str, function (err, conn) {
if (err) {
console.log("error", err);
res.end("error");
return;
}
conn.queryRaw("SELECT * FROM ProductLinks", function (err, results) {
if (err) {
res.end('failed2');
return;
}
for (var i = 0; i < results.rows.length; i++) {
blah += "Id: " + results.rows[i][0] + " Name: " + results.rows[i][1] + " Text: " + results.rows[i][2] + " Link: " + results.rows[i][3];
}
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(blah);
});
});
}).listen(process.env.PORT);
I have a feeling it may be down to permissions somewhere since it works locally and not remotely, but I'm not entirely sure. Plus when locally, Node JS is being executed under a different user as opposed to IIS_IUSR which IISNode uses.
Any help would be great, thanks!
I tried Node-MSSQL it's very good and very simple to use and it's connected and gets data successfully but it works on sql authentication only
I appear to have a memory leak with my Node.js application. I built it quickly, and my JavaScript isn't too strong, so this might be easy.
I've done some heap dumps on it, and it's the String object? leaking memory, at the rate of about 1MB every 5 minutes. I expanded String, and it's actually String.Array?
Heap stack:
#!/usr/local/bin/node
var port = 8081;
var io = require('socket.io').listen(port),
sys = require('sys'),
daemon = require('daemon'),
mysql = require('mysql-libmysqlclient');
var updateq = "SELECT 1=1";
var countq = "SELECT 2=2";
io.set('log level', 2);
process.on('uncaughtException', function(err) {
console.log(err);
});
var connections = 0;
var conn = mysql.createConnectionSync();
dbconnect();
io.sockets.on('connection', function(client){
connections++;
client.on('disconnect', function(){ connections--; })
});
process.on('exit', function () {
console.log('Exiting');
dbdisconnect();
});
function dbdisconnect() {
conn.closeSync();
}
function dbconnect() {
conn.connectSync('leet.hacker.org','user','password');
}
function update() {
if (connections == 0)
return;
conn.query(updateq, function (err, res) {
if (err) {
dbdisconnect();
dbconnect();
return;
}
res.fetchAll(function (err, rows) {
if (err) {
throw err;
}
io.sockets.json.send(rows);
});
});
}
function totals() {
if (connections == 0)
return;
conn.query(countq, function (err, res) {
if (err) {
// Chances are that the server has just disconnected, lets try reconnecting
dbdisconnect();
dbconnect();
throw err;
}
res.fetchAll(function (err, rows) {
if (err) {
throw err;
}
io.sockets.json.send(rows);
});
});
}
setInterval(update, 250);
setInterval(totals,1000);
setInterval(function() {
console.log("Number of connections: " + connections);
},1800000);
daemon.daemonize('/var/log/epiclog.log', '/var/run/mything.pid', function (err, pid) {
// We are now in the daemon process
if (err) return sys.puts('Error starting daemon: ' + err);
sys.puts('Daemon started successfully with pid: ' + pid);
});
Current version
function totals() {
if (connections > 0)
{
var q = "SELECT query FROM table";
db.query(q, function (err, results, fields) {
if (err) {
console.error(err);
return false;
}
for (var row in results)
{
io.sockets.send("{ ID: '" + results[row].ID + "', event: '" + results[row].event + "', free: '" + results[row].free + "', total: '" + results[row].total + "', state: '" + results[row]$
row = null;
}
results = null;
fields = null;
err = null;
q = null;
});
}
}
Still leaking memory, but it seems only on these conditions:
From startup, with no clients -> Fine
1st client connection -> Fine
2nd client (even with the 1st client disconnecting and reconnecting) -> Leaking memory
Stop all connections -> Fine
1 new connection (connections = 1) -> Leaking memory
Do yourself a favour and use node-mysql, it's a pure javascript mysql client and it's fast. Other than that, you should be using asynchronous code to stop IO being blocked whilst you're working. Using the async library will help you here. It has code for waterfall callback passing among other things.
As for your memory leaking, it probably isn't socket.io, although I haven't used it in a few months, I have had many thousands of concurrent connections and not leaked memory, and my code wasn't the best either.
Two things, however. Firstly your code is faily unreadable. I suggest looking into properly formatting your code (I use two spaces for every indentation but some people use four). Secondly, printing the number of connections every half an hour seems a little silly, when you could do something like:
setInterval(function() {
process.stdout.write('Current connections: ' + connections + ' \r');
}, 1000);
The \r will cause the line to be read back to the start of the line and overwrite the characters there, which will replace the line and not create a huge amount of scrollback. This will help with debugging if you choose to put debugging details in your logging.
You can also use process.memoryUsage() for quickly checking the memory usage (or how much node thinks you're using).
Could this be related to the connected clients array not clearing properly when a client disconnects? The array value gets set to NULL rather than being dropped from the array.