Sfoglia il codice sorgente

Check redis went away

walkor 3 anni fa
parent
commit
dbccc310c5
1 ha cambiato i file con 34 aggiunte e 3 eliminazioni
  1. 34 3
      src/Protocols/Http/Session/RedisSessionHandler.php

+ 34 - 3
src/Protocols/Http/Session/RedisSessionHandler.php

@@ -11,9 +11,11 @@
  * @link      http://www.workerman.net/
  * @license   http://www.opensource.org/licenses/mit-license.php MIT License
  */
-
 namespace Workerman\Protocols\Http\Session;
 
+use Workerman\Timer;
+use RedisException;
+
 /**
  * Class RedisSessionHandler
  * @package Workerman\Protocols\Http\Session
@@ -32,6 +34,11 @@ class RedisSessionHandler implements SessionHandlerInterface
     protected $_maxLifeTime;
 
     /**
+     * @var array
+     */
+    protected $_config;
+
+    /**
      * RedisSessionHandler constructor.
      * @param array $config = [
      *  'host'     => '127.0.0.1',
@@ -40,6 +47,7 @@ class RedisSessionHandler implements SessionHandlerInterface
      *  'auth'     => '******',
      *  'database' => 2,
      *  'prefix'   => 'redis_session_',
+     *  'ping'     => 55,
      * ]
      */
     public function __construct($config)
@@ -53,6 +61,19 @@ class RedisSessionHandler implements SessionHandlerInterface
             $config['timeout'] = 2;
         }
 
+        $this->_config = $config;
+
+        $this->connect();
+
+        Timer::add($config['ping'] ?? 55, function () {
+            $this->_redis->get('ping');
+        });
+    }
+
+    public function connect()
+    {
+        $config = $this->_config;
+
         $this->_redis = new \Redis();
         if (false === $this->_redis->connect($config['host'], $config['port'], $config['timeout'])) {
             throw new \RuntimeException("Redis connect {$config['host']}:{$config['port']} fail.");
@@ -82,7 +103,17 @@ class RedisSessionHandler implements SessionHandlerInterface
      */
     public function read($session_id)
     {
-        return $this->_redis->get($session_id);
+        try {
+            return $this->_redis->get($session_id);
+        } catch (RedisException $e) {
+            $msg = strtolower($e->getMessage());
+            if ($msg === 'connection lost' || strpos($msg, 'went away')) {
+                $this->connect();
+                return $this->_redis->get($session_id);
+            }
+            throw $e;
+        }
+
     }
 
     /**
@@ -125,4 +156,4 @@ class RedisSessionHandler implements SessionHandlerInterface
     {
         return true;
     }
-}
+}