He implementado el siguiente código:
module.exports = {
getDataFromUserGps: function(callback)
{
connection.connect();
connection.query("SELECT * FROM usergps",
function(err, results, fields) {
if (err) return callback(err, null);
return callback(null, results);
}
);
connection.end();
},
loginUser: function(login, pass, callback)
{
connection.connect();
connection.query(
"SELECT id FROM users WHERE login = ? AND pass = ?",
[login, pass],
function(err, results, fields)
{
if (err) return callback(err, null);
return callback(null, results);
}
);
connection.end();
},
getUserDetails: function(userid, callback)
{
connection.connect();
connection.query(
"SELECT * FROM userProfilDetails LEFT JOIN tags ON userProfilDetails.userId = tags.userId WHERE userProfilDetails.userid = ?",
[userid],
function(err, results, fields)
{
if (err) return callback(err, null);
return callback(null, results);
}
);
connection.end();
},
addTags: function(userId, tags)
{
connection.connect();
connection.query(
"INSERT INTO tag (userId, tag) VALUES (?, ?)",
[userId, tags],
function(err, results, fields)
{
if (err) throw err;
}
)
connection.end();
}
}
Todo funciona muy bien solo por primera vez. Si quiero "usar" la consulta por segunda vez, aparece el siguiente error:
Cannot enqueue Handshake after invoking quit
He intentado no hacer .end()
conexiones pero no ayudó.
¿Cómo puedo solucionar este problema?
connection.end
dentro de laconnection.query
función de devolución de llamada porque se ejecutará de forma asincrónica.Respuestas:
Si está utilizando el módulo node-mysql, simplemente elimine el .connect y .end. Solo resolví el problema yo mismo. Aparentemente, introdujeron código innecesario en su última iteración que también tiene errores. No es necesario que se conecte si ya ha ejecutado la llamada createConnection
fuente
De acuerdo a:
Arreglando Node Mysql "Error: No se puede poner en cola el Apretón de manos después de invocar salir":
http://codetheory.in/fixing-node-mysql-error-cannot-enqueue-handshake-after-invoking-quit/
y
Desde:
Readme.md - El servidor se desconecta:
https://github.com/felixge/node-mysql#server-disconnects
Dice:
He modificado la función de modo que cada vez que se necesita una conexión, una función de inicialización agrega los controladores automáticamente:
function initializeConnection(config) { function addDisconnectHandler(connection) { connection.on("error", function (error) { if (error instanceof Error) { if (error.code === "PROTOCOL_CONNECTION_LOST") { console.error(error.stack); console.log("Lost connection. Reconnecting..."); initializeConnection(connection.config); } else if (error.fatal) { throw error; } } }); } var connection = mysql.createConnection(config); // Add handlers. addDisconnectHandler(connection); connection.connect(); return connection; }
Inicializando una conexión:
var connection = initializeConnection({ host: "localhost", user: "user", password: "password" });
Sugerencia menor: es posible que esto no se aplique a todos, pero me encontré con un problema menor relacionado con el alcance. Si el OP considera que esta edición es innecesaria, puede optar por eliminarla. Para mí, tuve que cambiar una línea
initializeConnection
, que eravar connection = mysql.createConnection(config);
simplementeLa razón es que si
connection
es una variable global en su programa, entonces el problema anterior era que estaba creando una nuevaconnection
variable al manejar una señal de error. Pero en mi código de nodejs, seguí usando la mismaconnection
variable global para ejecutar consultas, por lo que la nuevaconnection
se perdería en el alcance local delinitalizeConnection
método. Pero en la modificación, asegura que laconnection
variable global se restablezca. Esto puede ser relevante si está experimentando un problema conocido comodespués de intentar realizar una consulta después de perder la conexión y luego reconectarse con éxito. Esto puede haber sido un error tipográfico del OP, pero solo quería aclararlo.
fuente
Tuve el mismo problema y Google me trajo hasta aquí. Estoy de acuerdo con @Ata en que no es correcto simplemente eliminar
end()
. Después de buscar más en Google, creo que usarpooling
es una mejor manera.Documento de node-mysql sobre la agrupación
Es como esto:
var mysql = require('mysql'); var pool = mysql.createPool(...); pool.getConnection(function(err, connection) { connection.query( 'bla bla', function(err, rows) { connection.release(); }); });
fuente
No conecte () y end () dentro de la función. Esto causará problemas en llamadas repetidas a la función. Haz la conexión solamente
var connection = mysql.createConnection({ host: 'localhost', user: 'node', password: 'node', database: 'node_project' }) connection.connect(function(err) { if (err) throw err });
una vez y reutilice esa conexión.
Dentro de la función
function insertData(name,id) { connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) { if(err) throw err }); }
fuente
Funciones de AWS Lambda
De esta manera, las nuevas invocaciones usan el grupo establecido, pero no mantienen la función en ejecución. Aunque no obtiene el beneficio completo de la agrupación (cada nueva conexión usa una nueva conexión en lugar de una existente), hace que una segunda invocación pueda establecer una nueva conexión sin que la anterior tenga que cerrarse primero.
Respecto a
connection.end()
Esto puede provocar que una invocación posterior arroje un error. La invocación se reintentará más tarde y funcionará, pero con un retraso.
Respecto
mysql.createPool()
aconnection.release()
La función Lambda seguirá ejecutándose hasta el tiempo de espera programado, ya que todavía hay una conexión abierta.
Ejemplo de código
const mysql = require('mysql'); const pool = mysql.createPool({ connectionLimit: 100, host: process.env.DATABASE_HOST, user: process.env.DATABASE_USER, password: process.env.DATABASE_PASSWORD, }); exports.handler = (event) => { pool.getConnection((error, connection) => { if (error) throw error; connection.query(` INSERT INTO table_name (event) VALUES ('${event}') `, function(error, results, fields) { if (error) throw error; connection.destroy(); }); }); };
fuente
en lugar de
connection.connect();
uso -if(!connection._connectCalled ) { connection.connect(); }
si ya está llamado entonces
connection._connectCalled =true
,& no se ejecutará
connection.connect()
;nota - no usar
connection.end();
fuente
Creo que este problema es similar al mío:
Resolví este problema recreando una nueva conexión con el uso de promesas (q).
mysql-con.js
'use strict'; var config = require('./../config.js'); var colors = require('colors'); var mysql = require('mysql'); var q = require('q'); var MySQLConnection = {}; MySQLConnection.connect = function(){ var d = q.defer(); MySQLConnection.connection = mysql.createConnection({ host : 'localhost', user : 'root', password : 'password', database : 'database' }); MySQLConnection.connection.connect(function (err) { if(err) { console.log('Not connected '.red, err.toString().red, ' RETRYING...'.blue); d.reject(); } else { console.log('Connected to Mysql. Exporting..'.blue); d.resolve(MySQLConnection.connection); } }); return d.promise; }; module.exports = MySQLConnection;
mysqlAPI.js
var colors = require('colors'); var mysqlCon = require('./mysql-con.js'); mysqlCon.connect().then(function(con){ console.log('connected!'); mysql = con; mysql.on('error', function (err, result) { console.log('error occurred. Reconneting...'.purple); mysqlAPI.reconnect(); }); mysql.query('SELECT 1 + 1 AS solution', function (err, results) { if(err) console.log('err',err); console.log('Works bro ',results); }); }); mysqlAPI.reconnect = function(){ mysqlCon.connect().then(function(con){ console.log("connected. getting new reference"); mysql = con; mysql.on('error', function (err, result) { mysqlAPI.reconnect(); }); }, function (error) { console.log("try again"); setTimeout(mysqlAPI.reconnect, 2000); }); };
Espero que esto ayude.
fuente
SOLUCIÓN: para evitar este error (para AWS LAMBDA):
Para salir del "bucle de eventos de Nodejs", debe finalizar la conexión y luego volver a conectarse. Agregue el siguiente código para invocar la devolución de llamada:
connection.end( function(err) { if (err) {console.log("Error ending the connection:",err);} // reconnect in order to prevent the"Cannot enqueue Handshake after invoking quit" connection = mysql.createConnection({ host : 'rds.host', port : 3306, user : 'user', password : 'password', database : 'target database' }); callback(null, { statusCode: 200, body: response, }); });
fuente
Si está tratando de obtener una lambda, descubrí que terminar el controlador con hace
context.done()
que la lambda termine. Antes de agregar esa 1 línea, simplemente se ejecutaría y se ejecutaría hasta que se agotara el tiempo.fuente
Puede usar debug: false,
Ejemplo: // conexión mysql
var dbcon1 = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "node5", debug: false, });
fuente