简体   繁体   English

PHP套接字服务器中的数据库连接

[英]DB Connection in PHP Socket Server

I'm running a Yii2 console application which starts a websocket chat service. 我正在运行启动Websocket聊天服务的Yii2控制台应用程序。 That all is working fine and as it's supposed to, but after some time of inactivity I get SQLSTATE[HY000]: General error: 2006 MySQL server has gone away . 一切正常,并按预期进行,但是经过一段时间的不活动后,我得到了SQLSTATE[HY000]: General error: 2006 MySQL server has gone away I tried to increase timeouts, set the user abort to false and to set PDO::ATTR_PERSISTENT => true in the PDO 's constructor, but this is still happening. 我试图增加超时时间,将用户abort设置为false,并在PDO的构造函数中将PDO::ATTR_PERSISTENT => true设置PDO::ATTR_PERSISTENT => true ,但这仍在发生。

Is there a way to check if a database connection is still active or if not how to reconnect to the db. 有没有一种方法可以检查数据库连接是否仍然处于活动状态,或者如果没有,如何重新连接到数据库。 Either in pure php or better with the Yii2 framework. 使用纯PHP或使用Yii2框架更好。

I had a similar problem and solved it by creating my own class for DB connection, which ensures that connection is active before actual query. 我遇到了类似的问题,并通过为数据库连接创建自己的类来解决此问题,该类确保在实际查询之前连接处于活动状态。

class DbConnection extends \yii\db\Connection {

    private $stamp;

    /**
     * {@inheritdoc}
     */
    public function createCommand($sql = null, $params = []) {
        try {
            // send ping on every 10 seconds
            if ($this->stamp < time()) {
                $this->stamp = time() + 10;
                parent::createCommand('SELECT 1')->execute();
            }
        } catch (\yii\db\Exception $e) {
            // if ping fail, reconnect
            $this->close();
            $this->open();
        }
        return parent::createCommand($query);
    }
}

Once every 10 seconds it sends "ping" query before creating a command. 每隔10秒,它会在创建命令之前发送“ ping”查询。 If ping fails (connection was interrupted), it tries to reconnect. 如果ping失败(连接中断),它将尝试重新连接。

This will not prevent from disconnecting, but it will automatically reconnect in case if connection was interrupted. 这不会阻止断开连接,但是如果连接中断,它将自动重新连接。 This may be tricky if you're using transactions - if connection is interrupted in the middle of transaction, transaction will be implicitly rollback by DB, and above code will implicitly reconnect, so you don't even notice that your transaction was rollback at some point. 如果您正在使用事务,这可能会很棘手-如果在事务中间连接中断,则数据库将隐式回滚事务,并且上面的代码将隐式重新连接,因此您甚至都不会注意到事务在某些时候已回滚。点。

Also I didn't test it in master-slave configuration. 另外,我没有在主从配置中对其进行测试。 But it worked perfectly fine in my case (read only connection to single server), so you may use it as a base and adjust for your needs with additional checks for transactions or master/slave connections. 但是在我的情况下,它工作得很好(只读连接到单个服务器),因此您可以将其用作基础,并通过对事务或主/从连接的附加检查来调整您的需求。

Not sure about where exactly you should go for this code exactly, but the concerned code to check if the connection is active following methods in yii\\db\\Connection class can be used 不知道确切应该在哪里找到此代码,但是可以使用以下代码检查连接是否处于活动状态: yii\\db\\Connection类中的以下方法

getIsActive() : Returns a value indicating whether the DB connection is established. getIsActive() :返回一个值,该值指示是否建立了数据库连接。

and to reconnect you can use 并重新连接,您可以使用

open() : Establishes a DB connection. open() :建立数据库连接。 It does nothing if a DB connection has already been established. 如果已建立数据库连接,则不执行任何操作。

if(Yii::$app->db->isActive === FALSE){
     Yii::$app->db->open();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM