Cannot enqueue Handshake after invoking quit的解決方案

前言

最近學習用node連接mysql數據庫,遇到了一個問題。
因爲數據庫的連接會佔用cpu,所以我設置,在每次請求的時候與數據庫進行連接,在每次請求結束之後,斷開與數據庫之間的連接。
當你在發出請求的時候執行connection.connect(),無論你在請求末尾是否使用了connection.end(),當你再次請求時,都會視爲你進行了一次新的連接。因此你需要執行創建新連接的操作
connection = mysql.createConnection(connection.config);
否則就會報錯Cannot enqueue Handshake after invoking quit(調用Quit後無法排隊握手)

對於這個錯誤,我想到了幾個解決辦法

  1. 在還沒有進行請求的時候,就建立與數據庫的連接,在請求結束之後,不斷開與數據庫的連接。即沒有connection.end();
    但這個想法有一個問題,即如果發生了意外事件,導致與數據庫連接的斷開時,我們就沒辦法再重連了
    這時候我們就需要監聽連接的error事件,當因爲某一些我們無法控制的錯誤導致數據庫的連接斷開時,我們就需要創建一個新的連接,並與之連接。

  2. 當每次進行請求時,創建一個新的連接(其實第一次是連接的時候)是不需要創建的
    connection = mysql.createConnection(connection.config);
    connection.connect()
    每當請求結束時,斷開連接
    connection.end();

const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
var server = new express();
var connection = mysql.createConnection({
    host:'localhost',
    user:'root',
    password:'191026',
    database:'weekly'
})
//位置1
//connection.connect();

// handleDisconnect(connection);
//當使用方法1的時候使用
//登錄接口
server.use(bodyParser.urlencoded({}))
server.listen(8082);
server.post('/weekly_war/user/register.do',function(req,res){
    console.log("註冊:");
    console.log(req.body);
    var user = req.body;
    var data;
    // 註冊成功需要滿足以下條件
    // 1.用戶名不能爲空
    if(!user.email){
        data = {
            msg:"參數爲空",
            code:1003,
            success:false
        };
        res.write(JSON.stringify(data));
        res.end();
    }else if(user.password.length<4||user.password.length>18){
     // 2.密碼的長度符合要求
       data = {
                msg:"註冊失敗,密碼長度不對!",
                code:1004,
                success:false
            };
            res.write(JSON.stringify(data));
            res.end();
    }else{
    // 3.用戶名在數據庫中不存在
    //在數據庫中創建一個user表,保存註冊的用戶信息
    //當要新添入用戶的時候,就查看user表,如果有相同的用戶名,那麼註冊成功,否則註冊失敗。
    //位置2
    connection = mysql.createConnection(connection.config);
    connection.connect();
    var addSql = "INSERT INTO user(weekly_id,weekly_email,weekly_password,weekly_phone) VALUES(0,?,?,?)";
    var addSqlParams = [user.email,user.password,user.phone];
    //增加成員
    connection.query(addSql,addSqlParams,function(err,result){
        if(err){
            data = {
                msg:"註冊失敗,用戶名已存在",
                code:4000,
                success:false
            }
            res.write(JSON.stringify(data));
        }else{   
            data = {
                msg:"註冊成功",
                code:2000,
                success:true,
                user:{
                    //id要從數據庫中獲取
                    "id":result.insertId,
                    "email":null,
                    "password":null,
                }
            }
            res.write(JSON.stringify(data));
            //註冊成功,再終止數據庫的連接
            // connection.end();
            // console.log('INSERT ID:',result.insertId);
        }
        res.end();
        });
        // connection.end();
    }
    //結束響應
});
// server.post('/weekly_war/user/login.do',function(req,res){
//     console.log("登錄:");
//     console.log(req.body);
// })


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

當然,這樣原生的建立以及終端連接太麻煩了,接下來我將使用連接池。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章