<?php
namespace app\common\lib;
class redisQueue {
    protected $options = [
        'host'       => '127.0.0.1',
        'port'       => 6379,
        'password'   => '',
        'select'     => 3,
        'timeout'    => 0,
        'expire'     => 172800,
        'persistent' => false,
        'prefix'     => '',
    ];
    protected  $handler = null ;
            
    function __construct($option=array()) {
        if(!$this->handler){
            $this->connect($option);
        }
    }
    
    public function connect($options=array()){
        if(!$this->handler){
            if (!extension_loaded('redis')) {
                throw new \BadFunctionCallException('not support: redis!');
            }
            if (!empty($options)) {
                $this->options = array_merge($this->options, $options);
            }
            $func          = $this->options['persistent'] ? 'pconnect' : 'connect';
            $this->handler = new \Redis;
            $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']);
            if ('' != $this->options['password']) {
                $this->handler->auth($this->options['password']);
            }
            if (0 != $this->options['select']) {
                $this->handler->select($this->options['select']);
            }
        }
        return $this;
    }
    // 从左侧弹出队列中的值，阻塞
    public function blPop($listName,$time=3600) {
        session_write_close();
        $this->handler->setOption(\Redis::OPT_READ_TIMEOUT, 3600);
        return $this->handler->blPop($this->options['prefix'].$listName,$time);
    }
    // 从右侧弹出队列中的值，阻塞
    public function brPop($listName,$time = 3600) {
        session_write_close();
        $this->handler->setOption(\Redis::OPT_READ_TIMEOUT, 3600);
        return $this->handler->brPop($this->options['prefix'].$listName,$time);
    }
    // 从队列右侧插入一条数据
    public function rPush($listName,$message) {
        $message = json_encode($message);
        return $this->handler->rPush($this->options['prefix'].$listName,$message);
    }
    // 从队列左侧插入一条数据
    public function lPush($listName,$message) {
        $message = json_encode($message);
        return $this->handler->lPush($this->options['prefix'].$listName,$message);
    }
    // 想频道中发送一条消息
    public function publish($channel,$message) {
        $message = json_encode($message);
       return $this->handler->publish($this->options['prefix'].$channel,$message);
    }
    // 订阅一个频道
    public function subscribe($channel,$callBack){
        session_write_close();
        $this->handler->setOption(\Redis::OPT_READ_TIMEOUT, 50);
        try {
            return $this->handler->subscribe($this->options['prefix'].$channel,$callBack);
        } catch (\Exception $e) {
            return false;
        }
    }
    // 设置
    public function setOption($option,$value){
        $this->handler->setOption($option,$value);
        return $this;
    }
    public function get($key){
        if($key){
            $value = $this->handler->get($this->options['prefix'].$key);
            $jsonValue = json_decode($value,true);
            return $jsonValue = null?$value:$jsonValue;
        }else{
            return false;
        }
    }
    public function set($key,$value,$expire=0){
        if($key && $value){
            $expire = intval($expire);
            $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value;
            if($expire){
                return $this->handler->setex($this->options['prefix'].$key,$expire,$value);
            }else{
                return $this->handler->set($this->options['prefix'].$key,$value);
            }
            
        }
    }
    public static function init($option = array()){
        //return new 
        $option = $option?array_merge(config('redis'),$option):config('redis');
        return new redisQueue($option);
    }
    public function getInstance(){
        return $this->handler;
    }

}