Node.js 调用quit后无法将握手排队
我已经实现了以下代码:Node.js 调用quit后无法将握手排队,node.js,express,Node.js,Express,我已经实现了以下代码: module.exports = { getDataFromUserGps: function(callback) { connection.connect(); connection.query("SELECT * FROM usergps", function(err, results, fields) { if (err) return ca
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();
}
}
一切都只是第一次很好。如果我想第二次“使用”查询,我会得到以下错误:
Cannot enqueue Handshake after invoking quit
我尝试不使用.end()
连接,但没有帮助
如何解决此问题?如果使用节点mysql模块,只需删除.connect和.end即可。我自己解决了这个问题。很明显,他们在上一次迭代中引入了不必要的代码,而这些代码也有缺陷。如果您已根据以下要求运行createConnection调用,则无需连接:
- 正在修复节点Mysql“错误:调用quit后无法将握手排队。”:
createConnection
方法来建立新连接
及
注意:如果您正在为web请求提供服务,那么您不应该在每个请求上都结束连接。只需在服务器上创建一个连接
启动并始终使用connection/client对象进行查询。
您可以侦听错误事件以处理服务器断开连接和
用于重新连接目的。完整代码
发件人:
- Readme.md-服务器断开连接:
err.code=
“协议连接丢失”
。看到错误了吗
有关更多信息,请参阅“处理”部分
处理此类意外断开的最佳方法如下所示:
function handleDisconnect(connection) {
connection.on('error', function(err) {
if (!err.fatal) {
return;
}
if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
throw err;
}
console.log('Re-connecting lost connection: ' + err.stack);
connection = mysql.createConnection(connection.config);
handleDisconnect(connection);
connection.connect();
});
}
handleDisconnect(connection);
正如您在上面的示例中所看到的,重新连接连接是非常困难的
通过建立新的连接来完成。一旦终止,现有的
无法通过设计重新连接连接对象
对于池,断开的连接将从池中删除
释放空间以便在下一个服务器上创建新连接
获取连接呼叫
我对函数进行了调整,使得每次需要连接时,初始化器函数都会自动添加处理程序:
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;
}
正在初始化连接:
var connection = initializeConnection({
host: "localhost",
user: "user",
password: "password"
});
次要建议:这可能不适用于所有人,但我确实遇到了与范围相关的次要问题。如果OP认为此编辑是不必要的,则他/她可以选择将其删除。对我来说,我必须更改initializeConnection
中的一行,即var connection=mysql.createConnection(config)代码>只需
connection = mysql.createConnection(config);
原因是,如果连接
是程序中的全局变量,那么之前的问题是在处理错误信号时创建了一个新的连接
变量。但是在我的nodejs代码中,我一直使用相同的全局connection
变量来运行查询,因此新的connection
将丢失在initializeconnection
方法的本地范围内。但是在修改中,它确保了全局连接
变量被重置。如果您遇到一个称为
出现致命错误后,无法将查询排队
在断开连接并成功重新连接后尝试执行查询。这可能是OP的错别字,但我只是想澄清一下。我也有同样的问题,谷歌把我带到了这里。我同意@Ata的观点,即仅仅删除end()
是不对的。在进一步的谷歌搜索之后,我认为使用pooling
是一种更好的方法
是这样的:
var mysql = require('mysql');
var pool = mysql.createPool(...);
pool.getConnection(function(err, connection) {
connection.query( 'bla bla', function(err, rows) {
connection.release();
});
});
我认为这个问题与我的类似:
连接到MySQL
结束MySQL服务(不应退出节点脚本)
启动MySQL服务,节点重新连接到MySQL
查询数据库->失败(致命错误后无法将查询排队。)
我通过使用承诺(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);
});
};
我希望这有帮助。不要在函数中连接()和结束()。这将导致重复调用函数时出现问题。只进行连接
var connection = mysql.createConnection({
host: 'localhost',
user: 'node',
password: 'node',
database: 'node_project'
})
connection.connect(function(err) {
if (err) throw err
});
一次,然后重新使用该连接
函数内部
function insertData(name,id) {
connection.query('INSERT INTO members (name, id) VALUES (?, ?)', [name,id], function(err,result) {
if(err) throw err
});
}
解决方案:为防止此错误(适用于AWS LAMBDA):
为了退出“Nodejs事件循环”,您必须结束连接,然后重新连接。添加下一段代码以调用回调:
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,
});
});
代替connection.connect()代码>使用-
if(!connection._connectCalled )
{
connection.connect();
}
如果已调用,则连接。_connectCalled=true
,
&它不会执行connection.connect()
注意-不要使用connection.end()代码>如果您试图获取lambda,我发现用context.done()
结束处理程序可以完成lambda。在添加这1行之前,它将一直运行,直到超时。AWS Lambda函数
将mysql.createPool()与connection.destroy()一起使用
这样,新调用使用已建立的池,但不保持函数运行。即使您没有获得池的全部好处(每个新连接使用一个新连接而不是一个现有连接),但它使第二次调用可以建立一个新连接,而不必首先关闭前一次调用
关于连接.end()
这可能会导致后续调用抛出错误。调用仍将稍后重试并工作,但会有延迟
关于mysql.createPool()
与connection.release()
Lambda函数将一直运行,直到计划的超时,因为仍然存在打开的连接
代码示例
你可以用
调试:错误
例如:
//mysql连接
var dbcon1 = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "node5",
debug: false,
});
你能至少结束这个问题吗?对我来说
var dbcon1 = mysql.createConnection({
host: "localhost",
user: "root",
password: "",
database: "node5",
debug: false,
});