簡體   English   中英

幾個小時后棘輪 WebSocket 連接到 mysql 數據庫錯誤 - SQLSTATE[HY000]:一般錯誤:2006 MySQL 服務器已消失

[英]Ratchet WebSocket connection to mysql database error after few hours - SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

目前,我已經在測試服務器上 dockerized 和部署了我的 web 應用程序。 在我的 docker 中,我正在運行帶有 mysql 數據庫的 Symfony4/React 全棧 Web 應用程序。 另外,我正在運行另一個運行 Ratchet websocket 的容器。 我的棘輪 websocket 從 mysql 數據庫中獲取數據。

在啟動這些服務后,我的 webapp 工作完全正常。 但是,在閑置幾個小時后,它開始出現以下錯誤。

SQLSTATE[HY000]:一般錯誤:2006 MySQL 服務器已經消失

web_1         | 202.21.101.226 - - [13/Dec/2019:08:39:50 +0000] "GET / HTTP/1.1" 200 1603 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
web_1         | - -  13/Dec/2019:08:39:50 +0000 "GET /index.php" 200
wss_1         | Client connected
wss_1         | Message Received
wss_1         | An exception occurred while executing 'SELECT t0.id AS id_1, t0.username AS username_2, t0.qrcode AS qrcode_3, t0.link AS link_4, t0.icon AS icon_5, t0.user_id AS user_id_6, t0.applink AS applink_7, t0.otp AS otp_8, t9.id AS id_10, t9.layout AS layout_11, t9.message AS message_12, t9.volume AS volume_13, t9.duration AS duration_14, t9.textcolor AS textcolor_15, t9.textsize AS textsize_16, t9.textweight AS textweight_17, t9.min_alert_donation AS min_alert_donation_18, t9.user_id AS user_id_19, t9.gif_id AS gif_id_20, t9.sound_id AS sound_id_21, t22.id AS id_23, t22.title AS title_24, t22.goal_amount AS goal_amount_25, t22.starting_amount AS starting_amount_26, t22.end_date AS end_date_27, t22.user_id AS user_id_28, t29.id AS id_30, t29.bg_color AS bg_color_31, t29.font_size AS font_size_32, t29.font_color AS font_color_33, t29.user_id AS user_id_34 FROM user t0 LEFT JOIN settings t9 ON t9.user_id = t0.id LEFT JOIN donation_goal_settings t22 ON t22.user_id = t0.id LEFT JOIN top_donator_settings t29 ON t29.user_id = t0.id WHERE t0.link = ? LIMIT 1' with params ["MTX6oPmIEKyDBVOFueRlhOi26WMWd1"]:
wss_1         | 
web_1         | 202.21.101.226 - - [13/Dec/2019:08:39:51 +0000] "GET /wss HTTP/1.1" 101 4 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
wss_1         | SQLSTATE[HY000]: General error: 2006 MySQL server has gone awayConnection 699 has disconnected

web_1:這是我的全棧應用

wss_1:這是我的 Ratchet websocket。

我在 phpMyAdmin 上運行“執行時發生異常”之后的 SQL 查詢。 它工作正常。

我不確定為什么我的 websocket 服務在空閑幾個小時后開始出現此錯誤。

任何建議將不勝感激! 提前致謝!

編輯:以下類處理我的 websocket 邏輯

class NotificationController implements MessageComponentInterface
{

    protected $clients;

    protected $container;

    protected $objectManager;

    public function __construct(ContainerInterface $container, ObjectManager $objectManager)
    {
        $this->container = $container;
        $this->objectManager = $objectManager;
        $this->clients = [];
    }

    /**
     * A new websocket connection
     *
     * @param ConnectionInterface $conn
     */
    public function onOpen(ConnectionInterface $conn)
    {
        echo "Client connected" . "\n";
    }

    /**
     * Handle message sending
     *
     * @param ConnectionInterface $from
     */
    public function onMessage(ConnectionInterface $from, $msg)
    {
        $myfile = fopen("./public/wsslog/log.txt", "w");
        try{
            $jsonData = json_decode($msg, true);
            echo "Message Received\n";
            if ($jsonData["request"] == "register") {
                $user = $this->objectManager->getRepository(\App\Entity\User::class)->findOneBy(["link" => $jsonData["code"]]);
                if($user){
                    $userId = $user->getUserId();
                    if(!isset($this->clients[$userId])){
                        $this->clients[$userId] = [$from];
                    }else{
                        array_push($this->clients[$userId], $from);
                    }
                }else{
                    $from->close();
                }
            } else {
                $from->close();
            }
        }catch(\Exception $e){
            echo $e->getMessage();
            fwrite($myfile, $e->getMessage()."\n");
            $from->close();
        }
    }

    /**
     * A connection is closed
     * @param ConnectionInterface $conn
     */
    public function onClose(ConnectionInterface $conn)
    {
        $conn->close();
        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    /**
     * Error handling
     *
     * @param ConnectionInterface $conn
     * @param \Exception $e
     */
    public function onError(ConnectionInterface $conn, \Exception $e)
    {
        echo "An error has occurred: {$e->getMessage()}\n";
        $myfile = fopen("./public/wsslog/log.txt", "w");
        fwrite($myfile, $e->getMessage()."\n");
        $conn->close();
    }

    public function notifiedFromSymfony($jsonString)
    {
        $jsonData = json_decode($jsonString, true);
        $userId = $jsonData["userId"];
        if (isset($this->clients[$userId])) {
            foreach($this->clients[$userId] as &$conn)
                $conn->send(json_encode(["amount" => $jsonData["amount"], "username" => $jsonData["username"]]));
        }
    }
}

從 mysql 客戶端到數據庫的打開連接不打算打開幾個小時。 一段時間后,客戶端斷開連接。 我正在為 Web 套接字客戶端使用以下數據庫包裝器:

class Database {
    private $pdo;
    private $params;

    public function __construct() {
        $this->params = func_get_args();
        $options = array(\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION);
        if(!in_array($options, $this->params, true)) {
            $this->params[] = $options;
        }
        $this->init();
    }

    public function __call($name, array $args) {
        return call_user_func_array(array($this->pdo, $name), $args);
    }

    public function ping() {
        try {
            $this->pdo->query('SELECT 1');
        }
        catch (\PDOException $e) {
            $this->init();
        }

        return true;
    }

    private function init() {
        $class = new \ReflectionClass('PDO');
        $this->pdo = null;
        $this->pdo = $class->newInstanceArgs($this->params);
    }
}

用法:

class WsClient {
    private $db;

    public function __construct($dsn, $user, $pwd) {
        $this->db = $db = new Database($dsn, $user, $pwd);
    }

    public function doSomething() {
        $this->db->ping();
        //execute query...
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM