How can I keep a constant MySQL connection alive in NodeJS - javascript

I'm currently developing Discord Bot, for data storing I'm using MySQL, but after some hours de connection dies. I was wondering if someone has a clue on how to do this. This the way I currently connect:
// Initalise Variables
var config;
var mysql, conn;
var fs;
try {
// External Packages
fs = require('fs');
config = require('./config.json');
mysql = require('mysql');
// Connection Setup
conn = mysql.createConnection({
host: config.mysql.host,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database
});
conn.connect();
} catch (e) {
console.error(e);
}

You can try changing the timeout setting else if would default to 10000ms or 10 seconds.
try {
// External Packages
fs = require('fs');
config = require('./config.json');
mysql = require('mysql');
// Connection Setup
conn = mysql.createConnection({
host: config.mysql.host,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database,
connectTimeout: config.mysql.timeout //1000000 some large number
});
conn.connect();
} catch (e) {
console.error(e);
}
You should probably use a connection pool instead of a single DB connection (this doesn't seem to have always keep alive type of setting, and you would have to give a large timeout like above)
try {
// External Packages
fs = require('fs');
config = require('./config.json');
mysql = require('mysql');
// Connection Setup
conn = mysql.createConnection({
host: config.mysql.host,
user: config.mysql.user,
password: config.mysql.password,
database: config.mysql.database,
connectionLimit: 10,
queueLimit: 20
});
var pool = mysql.createPool(config);
var queryDB = function(qry, cb) {
pool.getConnection(function(error, connection) {
if(error) {
cb(error, null);
}
else {
connection.query(qry, function (e, rows) {
connection.destroy();
cb(e, rows);
});
}
});

I think you need to install forever and start the service again. Forever is a simple CLI tool for ensuring that a given script runs continuously. Once you install forever and run the node js file then it will keeps the file alive continuously. Using npm you can install forever
npm install forever -g
Then just restart the js file
Ex:
forever start app.js
Hope now the js serves continously without breaking the connection.

Related

MariaDB NodeJS backend : too many connections

I have a NodeJS express backend which uses a MariaDB database.
My file dbconnect.js creates a mariadb pool and has a function to make queries.
const mariadb = require('mariadb');
const pool = mariadb.createPool({
host: process.env.DBHost,
user: process.env.DBUser,
database: process.env.DB,
password: process.env.DBSecret
});
const dbQuery = async(query) => {
let conn;
let res = '';
try {
conn = await pool.getConnection();
res = await conn.query(query);
} catch (err) {
console.log("Error sending Query: ", query, err.text);
} finally {
if (conn) {
conn.end();
}
return res;
}
}
Everything seems to work perfectly, but after a few months with the server running these messages begin to appear on the console:
These messages keep appearing every 10-14 seconds, but no queries are being performed.
Thanks for any help
I am not sure but there is one way,
configure your connection pool to ping at particular time. so it will close any inactive connections before the server closes them. mariadb has pingInterval for this
Replace this code with your code
const pool = mariadb.createPool({
host: process.env.DBHost,
user: process.env.DBUser,
database: process.env.DB,
password: process.env.DBSecret,
pingInterval: 60000
});
This will send a ping to the server every 60 seconds, which will prevent the server from closing inactive connections.

Node.js MySQL Connection Error. ECONNREFUSED

I have 2 servers, one running the frontend code (Node.js, express) and the other running MySQL with PHPMyAdmin, both are working standalone and I can confirm the MySQL database is running on 3306 but whenever I try to connect via Node.js (code below) I get a connection refused error.
const conn = mysql.createConnection({
host: '192.168.1.250',
user: 'mcd',
password: '**********',
database: 'mcd'
})
conn.connect(function(err) {
if (err) throw err;
})
The IP address I have used for the host is the IP address of the MySQL server. So unsure why it cannot connect since it is running on the default port.
Here is my connection to Node.js:
pool = mysql.createPool({host:"localhost"
,port:"3306"
,database:"db_name"
,user:"user_name"
,password:"password_for_user"
,timezone:"utc"
,multipleStatements:true
,max:1000
,min:1
,idleTimeoutMillis:defs.QUERY_TIMEOUT});
if ( pool && pool.getConnection ) {
pool.getConnection(function(errsts, conn) {
var resp = {};
if ( errsts ) {
resp['error'] = errsts;
return;
}
resp['state'] = "connected";
if ( cbRoutine ) {
cbRoutine(conn, resp, objParams);
if ( conn != undefined ) {
conn.release();
}
}
});
}
localhost is correct for my usage, you should replace its your name or IP address.
defs.QUERY_TIMEOUT is defined in my source as:
var QUERY_TIMEOUT = 10 * 1000;
In my code cbRoutine is a call back function passed in as a parameter to call on successful connection.
The ECONNREFUSED error indicates that it can't connect to where the function is hosted (in this case localhost)
dbConnection.js
const mysql = require('mysql');
const connection = mysql.createPool({
connectionLimit: 10, // default = 10
host: '127.0.0.1',
user: 'root',
password: '',
database: 'dname'
});
module.exports = connection;

Error Connecting to the database: Error: ER_NOT_SUPPORTED_AUTH_MODE: Client does not support authentication protocol requested by server

I've tried following the suggestion at this link: MySQL 8.0 - Client does not support authentication protocol requested by server; consider upgrading MySQL client
and am aware that it is using cahcing_sha2_password instead of mysql_native. However, I've tried following the suggestions and am still receiving the same errors, trying to connect to the database with node.
Schema name: 'my_db'
//DATABASE CONNECTION SETTINGS
const APIServerPort = 3001;
const database = {
host: "localhost",
port: 3306,
user: "root",
password: "xxx",
database: "my_db"
};
module.exports = {
database,
APIServerPort
};
app.js file:
const express = require("express");
const app = express();
const router = express.Router();
const settings = require("./settings");
const routes = require("./routes");
const mysql = require("mysql");
const connection = mysql.createConnection(settings.database);
router.get("/employees", routes.employees.listAllEmployees);
app.use("/apis", router);
connection.connect(error => {
if (error) {
console.error("Error Connecting to the database: " + error);
return process.exit();
}
app.listen(settings.APIServerPort, () =>
console.info(`Server is running at port ${settings.APIServerPort}...`)
);
});
SQL Queries Ran:
CREATE USER 'root'#'localhost:3301/apis/employees' IDENTIFIED WITH mysql_native_password BY 'xxx';
FLUSH PRIVILEGES;
I'm still receiving the same error however.
mysql users are in the form 'root'#'localhost'. Urls are a node.js concept only.
As that user already exists create a new one:
CREATE USER myapplication#localhost
IDENTIFIED WITH mysql_native_password BY 'xxx';
GRANT ALL ON my_db.* TO myapplication#localhost`;
You don't need FLUSH PRIVILEGES.

Issue connecting to my sql database using a REST api server with Node.js

I'm very new to coding servers and javascript in general but I'm currently trying to set up a REST api server and connect it to my sql database, for the moment I am doing everything locally. I am running ubuntu 18.04 while using NODE js. I have been able to successfully create a REST api and connect to it through an url of a webpage or with Postman. I have created a sql server database through my cmd terminal and have created test data on it. I've been looking at guides to connect the REST api to the database but I think the info I'm giving the api to connect is where my issue is occurring. I am starting with this below as my server.js where i have a folder Controller and a ProductController.js file where I'm handling the route /api/products .
var http = require('http');
var express = require('express');
var app = express();
var port = process.env.port || 3000;
var productController = require('./Controller/ProductController')();
app.use("/api/products", productController);
app.listen(port, function(){
var datetime = new Date();
var message = "Server running on Port:- " + port + " Started at :- " +
datetime;
console.log(message);
});
Below is my ProductController.js file. The issue might be here but I believe it is my next file called connect.js the table in my sql database is called 'data' hence the "SELECT * FROM data" part. when I try to GET this data in postman it displays the error i set up "Error while inserting data". so I believe when running I'm not getting data from sql so conn.close() is not being reached.
var express = require('express');
var router = express.Router();
var sql = require("mssql");
var conn = require("../connection/connect")();
var routes = function()
{
router.route('/')
.get(function(req, res)
{
conn.connect().then(function()
{
var sqlQuery = "SELECT * FROM data";
var req = new sql.Request(conn);
req.query(sqlQuery).then(function (recordset)
{
res.json(recordset.recordset);
conn.close();
})
.catch(function (err) {
conn.close();
res.status(400).send("Error while inserting data");
});
})
.catch(function (err) {
conn.close();
res.status(400).send("Error while inserting data");
});
});
return router;
};
module.exports = routes;
This is my connect.js file below. I have a password for root which is not *** but is correct on my machine. I have changed root's plug in to mysql_native_password in the mysql terminal. I think the server: part is wrong, I've tried commenting it out but still no connection. I do not have SQL Server Management Studio and have not found a way to get my sql server's name through the terminal. I've seen examples that seem to range of what info you need to give the api to connect. If someone has insight on that too that would be appreciated as well. My end goal is to eventually create GET and POST routes for the database and a function to manipulate the POST data but for now I'm just trying to get things connected so I can play around with the data being GET'ed. Thanks for any insight you can give, it is much appreciated.
var sql = require("mssql");
var connect = function()
{
var conn = new sql.ConnectionPool({
host: 'localhost'
user: 'root',
password: '********',
server: 'mysql',
database: 'test'
});
return conn;
};
Looks like you may have some errors in your connect.js file:
var conn = new sql.ConnectionPool({
host: 'localhost'
user: 'root',
password: '********',
server: 'mysql',
database: 'test'
});
should be in the format of:
const pool = new sql.ConnectionPool({
user: '...',
password: '...',
server: 'localhost',
database: '...'
})
Note that you currently have both host and server, looks like only server is needed. Also, server: 'mysql' doesn't make sense if you are connecting to a MSSQL database.
Source: node-mssql documentation
To diagnose the errors you should add some logging to your catch blocks:
.catch(function (err) {
console.log('connection error', err); //or Bunyan, Winston, Morgan, etc. logging library
conn.close();
let message = "Error while inserting data"
if (process.env.NODE_ENV === 'development') { //conditionally add error to result message
message += "\n"+err.toString());
}
res.status(500).send(message); //use 5xx for server problems, 4xx for things a user could potentially fix
});
And set NODE_ENV in your environment, for example in package.json:
"scripts": {
"start": "NODE_ENV=production node app.js"
"start-dev": "NODE_ENV=development node app.js"
}

Connect Nodejs and Angular 2 to SQL Server 2014

I am using Angular 2 and Nodejs to Connect to an SQL Server. If I simply put following code in a js file and run it through the console using node test.js the code deletes the record properly.
Here is the code:
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
After that I moved the same file to the src folder in my Angular 2 project (where the index.html file also exists). I put the same code into a function in test.js file like that:
function testConnection()
{
var webconfig = {
user: 'sa',
password: 'test',
server: 'localhost',
database: 'Test',
options: {
encrypt: false // Use this if you're on Windows Azure
}
}
var express = require('express');
var sql = require('mssql');
var http = require('http');
var app = express();
var port = process.env.PORT || 4200;
var connection = new sql.Connection(webconfig, function(err) {
var request = new sql.Request(connection);
request.query('delete from Employee where Id = 2382', function(err, recordset) {
if(err) // ... error checks
console.log('Database connection error');
console.dir("User Data: "+recordset);
});
});
app.listen(port);
console.log(port+' is the magic port');
}
Now I want to call testConnection() from the index page. I have put the <script src="C:\Users\amandeep.singh\Desktop\Angular\my-app\src\test.js"> to script path and call the function using this:
<script>
testConnection();
</script>
The index page executes properly but doesn't show any error nor executes the command. I'm unable to understand why the same code works in the console on Nodejs but not in my index.html.
Help will be appreciated.
You can't run Node applications in the browser. Nodejs is an application that runs Javascript in Google's V8 Javascript VM on your operating system and is meant to be a backend system (at least in the web development stack).
So you basically have to run your Node program on a webserver and make your API requests from the Angular application.
There are several tutorials out there on the internet that help you with this.
Here is the official Angular documentation angular.io

Categories