Nodejs cannot load the page when I connect to MySQL? - mysql

I can run other programs on node.js with no problem. When I want to connect to MySQL through NODE.js it loads forever when I type nodejs mysqlConnection.js in terminal and http://localhost:8080/ in browser.
My Code is as below:
// Include http module,
var http = require('http'),
// And mysql module you've just installed.
mysql = require("mysql");
// Create the connection.
// Data is default to new mysql installation and should be changed according to your configuration.
var connection = mysql.createConnection({
user: "root",
password: "",
database: "framework"
});
// Create the http server.
http.createServer(function (request, response) {
// Attach listener on end event.
request.on('end', function () {
// Query the database.
connection.query('SELECT * FROM words;', function (error, rows, fields) {
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
// Send data as JSON string.
// Rows variable holds the result of the query.
response.end(JSON.stringify(rows));
});
});
// Listen on the 8080 port.
}).listen(8080);
NB: MySQL connection is correct because I connect to my database via PHP with no problem.
NB: I have a folder named node_modules beside to my js file, inside it I have mysql folder.
I tried to install nodejs through npm:

A request is ended only when the response has been sent.
You're waiting for the end event without ever sending a response (because that response is sent from within the end handler, resulting in a sort of deadlock situation).
As #vkurchatkin points out in the comments, if the request stream is being consumed, the end handler will be called once it has been consumed entirely, independent of the state of the response. In this case, the request wasn't being consumed at all, meaning that the end handler would have been called (as part of the request teardown, probably) only after the response was sent.
So removing the end handler altogether should fix the problem:
http.createServer(function (request, response) {
connection.query(..., function(error, rows, fields) {
// TODO: handle `error`
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
response.end(JSON.stringify(rows));
});
});

Related

REACT NATIVE Retrieving data from localhost MySQL database

I'm writing an app in React Native and I have created a MySQL database to store my information, but I was wondering if it was possible to use axios or fetch to interact with my database since it's local and doesn't have an HTTP address yet?
I feel like I used to be able to do it, but I forgot the syntax to use... If anyone knows anything, I would greatly appreciate it.
Thank you
There is no direct connection between React Native and Mysql. So you need to use Node js.
Step 1:
npm install express
npm install body-parser
npm install mysql
Step 2:
const connection = mysql.createPool({
host : 'localhost', // Your connection adress (localhost).
user : 'root', // Your database's username.
password : '', // Your database's password.
database : 'my_db' // Your database's name.
});
// Starting our app.
const app = express();
// Creating a GET route that returns data from the 'users' table.
app.get('/users', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query('SELECT * FROM users', function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('Go to http://localhost:3000/users so you can see the data.');
});
To get the data in your React Native App. You need to use your PC's IP Address. If you use localhost you access the smartphone/emulator localhost. Here is an example to follow:
getData(){
fetch('http://yourpcip:3000/users')
.then(response => response.json())
.then(users => console.log(users))

Amazon RDS load balancing not working with mysql.createPool in nodejs

I have implemented load balancing in read database connection like when read db load increased to 60% it will initiate a new read database for balancing load on database but
When I see from AWS developer console dashboard all API calls It will initate new read database instance but most of the API's calls load took placed on database 1 upto 90 percent but like 10 req /sec and on read DB instance 2 1 to 5% database is used like 1req /sec
it should divided API request on both database equaly but It wont work
This issue is because mysql.createPool will not close connection from database 1 (createPool will reuse its opened connections) so that other API calls can move to second database instance.
To solve this problem I had changed mysql.createPool with mysql.createConnection on Each API calls
I had created 2 middleware
1-for createConnection
2-for connection.end()
whenever a request comes in middleware 1 calls and create new connection and on request finish middleware 2 will call which will end the connection. this solution has solved my problem of load balancing but a new issue takes place I have face to many database connection issues with this method
does anyone have a proper solution who has faced this issue or can help?
Sample Code :
var readDB = mysql.createConnection({
database: process.env.READ_DB_DATABASE,
host: process.env.READ_DB_HOST,
user: process.env.READ_DB_DB_USER,
password: process.env.READ_DB_DB_PASSWORD,
charset: "utf8mb4"
});
utils.js
async onFinish(req, res, next) {
return new Promise(async (resolve, reject) => {
try {
let readDB = req.readDB;
const dbEnd = util.promisify(readDB.end).bind(readDB);
const response = await dbEnd();
resolve(response);
} catch (error) {
reject(error);
}
});
}
app.js
/**
* middleware for create connection and end connection on finish
*/
app.use(async (req, res, next) => {
try {
const readDB = await utils.readDBCreateConnection();
req.readDB = readDB;
res.on("finish", function () {
console.log("onFinish called");
utils.onFinish(req, res, next);
});
next();
} catch (error) {
res.status(error.status || 500).send({
code: 500,
message: error.message || `Internal Server Error`,
});
}
});
/**
* Code to initialice routing
*/
require("./modules/v2-routes")(app); // v2 app routes

How to properly set up node js rest api

Im a android dev and trying to make a simple rest api with node js, so Im basically new to js.
Im setting up a new rest api and want to connect to mysql database.
I was trying to solve that this way, but I'm getting errors.
And, also how many connection limits to set ?
const express = require('express');
const db = require('../db');
const mainNewsRouter = express.Router();
mainNewsRouter.get('/', async (req, res, next) => {
try {
let result = await db.getMainNews();
console.log(res.json(result));
res.json(result);
} catch(e) {
console.log(e);
}
});
module.exports = mainNewsRouter;
//DbHandler.js
var mysql = require('mysql2');
const url = require('url');
var SocksConnection = require('socksjs');
var remote_options = {
host:'xxx',
port: 3306
};
var proxy = url.parse('http://xxx:xxx#us-east-static-06.quotaguard.com:xxx');
var auth = proxy.auth;
var username = auth.split(":")[0];
var pass = auth.split(":")[1];
var sock_options = {
host: proxy.hostname,
port: 1080,
user: username,
pass: pass
};
var sockConn = new SocksConnection(remote_options, sock_options);
var dbConnection = mysql.createPool({
connectionLimit: 10,
user: 'xxx',
database: 'xxx',
password: 'xxx',
stream: sockConn
});
getMainNews = () => {
return new Promise((resolve, reject) => {
dbConnection.query('SELECT ... * from ...;',
(err, results) => {
if (err) {
return reject(err);
};
// sockConn.dispose();
return resolve(results);
});
});
dbConnection.end();
};
On first api call I get data from database, but with this error:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:470:11)
at ServerResponse.header (node_modules\express\lib\response.js:771:10)
at ServerResponse.send (node_modules\express\lib\response.js:170:12)
at ServerResponse.json (node_modules\express\lib\response.js:267:15)
at mainNewsRouter.get (server\routes\mainNews.js:10:11)
at process._tickCallback (internal/process/next_tick.js:68:7)
And after second API call there is no data, I only get this exception.
> Server is running on port: { Error: This socket has been ended by the
> other party
> at Socket.writeAfterFIN [as write] (net.js:395:12)
> at SocksConnection._write (node_modules\socksjs\socks.js:72:24)
> at doWrite (_stream_writable.js:415:12)
> at writeOrBuffer (_stream_writable.js:399:5)
> at SocksConnection.Writable.write (_stream_writable.js:299:11)
> at PoolConnection.write (node_modules\mysql2\lib\connection.js:221:17)
> at PoolConnection.writePacket(node_modules\mysql2\lib\connection.js:279:12)
> at ClientHandshake.sendCredentials (node_modules\mysql2\lib\commands\client_handshake.js:63:16)
> at ClientHandshake.handshakeInit (node_modules\mysql2\lib\commands\client_handshake.js:136:12)
> at ClientHandshake.execute (node_modules\mysql2\lib\commands\command.js:39:22) code: 'EPIPE',
> fatal: true }
Although I am by no means an expert, I think one of the issues lies with closing the connection. The whole idea of a pool is to release the connection back to the pool, not close it.
I have done testing on connection pools and have used a pool size of min:4 max:12 with 100s of requests per second without running into connections issues with MySQL.
Personally, I use Knex to manage my db connections, it manages all of the pools too, taking care of a lot of the headache. Low overhead, I think it would be worth porting over that part of your code to. Once the connection issue is sorted out, then you could tackle other issues as they crop up.
Again, I am not an expert and cannot exactly nail down releasing the MySQL connection back to the pool in the code above, but I do think that is why you don't get data after your initial call.
It wont answer your full question but still. The "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" means that a header has already been set but the user is again trying to set it. A header is set when we send a response. Headers include the content type, content-length,status and all the information about the response we are sending. When we write res.send or res.json or res.render i.e sending a response the headers get set automatically using the required information (Express does it automatically for us, in pure nodejs we have to set every header by ourselves). Notice that you have written res.json two times which means it has to set the headers twice. Also writing res.json inside console.log doesnt make any sense. Why have you done that?

Testing an AWS Lambda function

I need to create a lambda function to act as the middleman between a mobile Java app and an AWS RDS MySQL database. The idea is to submit queries from the mobile app and then send them off to the lambda function, which will then return the query. I have a basic MySQL query set up in my AWS lambda:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) -> {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
if (err) throw err; // not connected!
// Use the connection
connection.query('select Album from record', function (error, results, fields) {
// When done with the connection, release it.
connection.release();
// Handle error after the release.
if (error) callback(error);
else callback(null, results[0].Album);
// Don't use the connection here, it has been returned to the pool.
});
});
};
And all that I am currently trying to do is get this code to run and output what the query will return. I've seen tutorials where people seem to just click test and have the code run, but it keeps asking me to create a test, and I'm not sure what exactly I would need to do to test this function.
EDIT: I realized I was missing a small change in my lambda uploaded code, but I am now getting an error on line 10 saying there is an unexpected token >.
I'm not sure what's wrong here, as the tutorial I watched seems to have the same exact thing.
Since you're not passing in any parameters through the context, you can just create a test with the defaults or an empty object {}, and click Test in the console. It will invoke your Lambda function as if it had been called from your mobile app, and you can debug from there.

How to use express.js with mysql and express-myconnection?

I am using Express 4.9.0 and express-generator. Executed this command:
express --hbs projectname
Installed following modules with NPM:
mysql
express-myconnection
I want to make todo application. I have created separate file under routes/todo.js and created get/post routes for creating todos in that file using router.get and router.post.
i have following code in app.js:
// mysql connection
var connection = require('express-myconnection');
var mysql = require('mysql');
app.use(
connection(mysql, {
host : config.db.host,
user : config.db.user,
password : config.db.password,
database : config.db.database,
debug : false //set true if you wanna see debug logger
}, 'request')
);
// end of mysql connection
Where should i place mysql config and connection code? Inside todo.js? I still don't get concept of organisation file structure and where to place database queries.
I don't know if you eventually found the answer, but I thought it might help out others who accidentally stumbled on your question:
After you've setup like mentioned above, you can call the connection from the request object using the getConnection method like this:
exports.index = function(req, res) {
req.getConnection(function (err, connection) {
connection.query('select * from table_name', function(err, rows, fields){
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(rows);
}
});
});
};
This should print out a json with the content of your table all nice an pretty.
Hope this comes in handy.