Не удается поставить в очередь рукопожатие после вызова quit


здесь я делаю, вероятно, какую-то основную ошибку, в общем, я реализовал такой код:

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();
    }
}

и все работает отлично, но только в первый раз, если я хочу" использовать " запрос во второй раз, я получаю его ошибку:

Не удается поставить в очередь рукопожатие после вызова quit

Я старался не думать .конец () соединения, но это не помогает
Заранее спасибо
Радек

7 62

7 ответов:

Если вы используете модуль node-mysql, просто удалите его .подключение и. конец. Просто решил проблему сам. По-видимому, они вставили ненужный код в свою последнюю итерацию, которая также прослушивается. Вам не нужно подключаться, если вы уже выполнили вызов createConnection

по:

TL; DR вам нужно установить новое соединение по телефону createConnection метод после каждого отключения.

и

Примечание: если вы обслуживаете веб-запросы, то вы не должны заканчивать соединения по каждому запросу. Просто создайте соединение на сервере запуск и использование объекта подключения / клиента для запроса все время. Вы можете прослушать событие ошибки для обработки отключения сервера и для целей повторного подключения. Полный код здесь.


от:

он говорит:

сервер отключает

вы можете потерять соединение с сервером MySQL из-за сетевых проблем, тайм-аут сервера или сбой сервера. Все эти события считаются фатальными ошибками, и будет err.code = 'PROTOCOL_CONNECTION_LOST'. См. сообщение об ошибке Раздел обработки для получения дополнительной информации.

лучший способ справиться с такими неожиданными вылетами показано ниже:

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);

как вы можете видеть в примере выше, повторно соединяясь соединение сделано путем установления нового соединения. После завершения, существующий объект подключения не может быть повторно подключен по проекту.

с пулом отключенные соединения будут удалены из пула освобождение места для нового соединения, которое будет создано на следующем метод getconnection вызов.


я настроил функцию таким образом, что каждый раз, когда требуется соединение, функция инициализатора автоматически добавляет обработчики:

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);

причина в том, что если connection является глобальной переменной в вашей программе, то проблема раньше была в том, что вы делали новый connection переменной при обработке сигнала ошибки. Но в моем коде nodejs, я продолжал использовать тот же глобальный connection переменная для выполнения запросов, так что новый connection будет потерян в локальной области initalizeConnection метод. Но в модификации он гарантирует, что глобальный connection переменная сбрасывается это может быть актуально, если вы испытываете проблему, известную как

невозможно поставить запрос в очередь после фатальной ошибки

после попытки выполнить запрос после потери соединения и затем успешного повторного подключения. Возможно, это была опечатка ОП, но я просто хотел уточнить.

у меня была та же проблема, и Google привел меня сюда. Я согласен с @Ata, что это не правильно просто удалить end(). После дальнейшего гуглить, я думаю, с помощью pooling лучший способ.

node-mysql doc о объединении

это так:

var mysql = require('mysql');
var pool  = mysql.createPool(...);

pool.getConnection(function(err, connection) {
    connection.query( 'bla bla', function(err, rows) {
        connection.release();
    });
});

Не подключайте () и не завершайте () внутри функции. Это вызовет проблемы при повторных вызовах функции. Сделайте соединение только

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
  });


}

Я думаю, этот вопрос похож на мой:

  1. подключение к MySQL
  2. завершить службу MySQL (не следует выходить из скрипта узла)
  3. запустите службу MySQL, узел снова подключается к MySQL
  4. запрос к БД - > сбой (невозможно поставить запрос в очередь после фатальной ошибки.)

Я решил эту проблему, воссоздав новое соединение с использованием обещаний (вопрос.)

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);
    });
};

Я надеюсь, что это помогает.

устранение: чтобы предотвратить эту ошибку(для 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();
}

если он уже называется то connection._connectCalled =true,
и он не будет выполнять connection.connect();

Примечание - не используйте connection.end();