Подтвердить что ты не робот

Не удается выполнить авторизацию после вызова 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

Я пробовал не подключаться .end(), но это не помогает Спасибо заранее Радек

4b9b3361

Ответ 1

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

Ответ 2

В соответствии с:

TL; DR Вам необходимо установить новое соединение, вызвав метод createConnection после каждого отключения.

и

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


From:

В нем говорится:

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

Вы можете потерять соединение с сервером 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"
});

Незначительное предложение: Это может не относиться ко всем, но я столкнулся с незначительной проблемой, связанной с областью. Если ОП считает, что это редактирование не нужно, он может выбрать его удалить. Для меня мне пришлось изменить строку в initializeConnection, которая была var connection = mysql.createConnection(config); просто просто

connection = mysql.createConnection(config);

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

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

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

Ответ 3

У меня была такая же проблема, и Google привел меня сюда. Я согласен с @Ata, что не правильно просто удалить end(). После дальнейшего Googling я думаю, что использование 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();
    });
});

Ответ 4

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

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


}

Ответ 5

Я думаю, что эта проблема похожа на мою:

  • Подключение к MySQL
  • Завершить службу MySQL (не следует оставлять node script)
  • Запустите службу MySQL, node подключится к MySQL
  • Запросить БД → FAIL (Невозможно задать запрос после фатальной ошибки.)

Я решил эту проблему, воссоздав новое соединение с использованием promises (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);
    });
};

Надеюсь, это поможет.

Ответ 6

Функции AWS Lambda

Используйте mysql.createPool() с connection.destroy()

Таким образом, новые вызовы используют установленный пул, но не поддерживают функцию. Даже несмотря на то, что вы не получаете полного преимущества от пула (каждое новое соединение использует новое соединение вместо существующего), оно делает так, чтобы второй вызов мог установить новое соединение, при этом предыдущее соединение не нужно было закрывать первым.

Относительно connection.end()

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

Относительно mysql.createPool() с connection.release()

Функция Lambda будет работать до запланированного времени ожидания, так как соединение все еще остается открытым.

Пример кода

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

Ответ 7

РЕШЕНИЕ: для предотвращения этой ошибки (для AWS LAMBDA):

Чтобы выйти из цикла "Nodejs Event Loop", необходимо завершить соединение, а затем снова подключиться. Добавьте следующий код для вызова обратного вызова:

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,

        });
    });

Ответ 8

место connection.connect();.connect connection.connect(); использовать -

if(!connection._connectCalled ) 
{
connection.connect();
}

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

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

Ответ 9

Если вы пытаетесь получить лямбду, я обнаружил, что завершение обработчика context.done() заставило лямбду завершиться. Перед добавлением этой 1-й строки, он просто запустится и будет работать до истечения времени ожидания.

Ответ 10

Вы можете использовать отладку: ложь,

Пример://соединение mysql

var dbcon1 = mysql.createConnection({
      host: "localhost",
      user: "root",
      password: "",
      database: "node5",
      debug: false,
    });