TP使用redis消息订阅

分类首页日期2年前访问1340评论0

第一步:在redis配置文件开启EX扩展,notify-keyspace-events Ex,如果是windows服务器redis配置文件是redis.windows.conf文件,把notify-keyspace-events Ex放开就行了

第二步:添加代码,新建一个redis类:application\common\library\RedisEx.php,RedisEx.php自己随意命名,代码如下:

<?php
/**

 * Createsd by PhpStrom
 * User Fuzhenzhuo
 * mail 309657536@qq.com
 * Date 2020/8/11
 * Time 10:40
 */

namespace app\common\library;

use think\cache;

class RedisEx
{
    public function __construct()
    {
        ini_set('default_socket_timeout', -1);

        $redis = Cache::store('redis')->handler();

        $this->redis = $redis;

    }

    public function setEx($key, $time, $val)
    {

        return $this->redis->setEx($key, $time, $val);
    }

    public function set($key, $val)
    {
        return $this->redis->set($key, $val);
    }

    public function get($key)
    {
        return $this->redis->get($key);
    }

    public function expire($key = null, $time = 0)
    {
        return $this->redis->expire($key, $time);
    }

    public function psubscribe($patterns = array(), $callback)
    {
        $this->redis->psubscribe($patterns, $callback);
    }

    public function setOption()
    {
        $this->redis->setOption(\Redis::OPT_READ_TIMEOUT, -1);
    }

    public function psCallback($redis,$pattern, $chan, $msg)
    {
        echo "Pattern: $pattern\n";
        echo "Channel: $chan\n";
        echo "Payload: $msg\n\n";
    }

}

把tp的缓存配置文件修改一下

第三步:在application下的command.php新增一行代码,代码:
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: yunwuxin <448901948@qq.com>
// +----------------------------------------------------------------------

return [
    'app\admin\command\Crud',
    'app\admin\command\Menu',
    'app\admin\command\Install',
    'app\admin\command\Min',
    'app\admin\command\Addon',
    'app\admin\command\Api',
    'leave'=>'app\common\command\Leave',//新增
];

第三步:新建application\common\command\Leave.php,代码如下:

<?php
/**

 * Createsd by PhpStrom
 * User Fuzhenzhuo
 * mail 309657536@qq.com
 * Date 2020/8/11
 * Time 11:53
 */

namespace app\common\command;

use app\common\library\RedisEx;
use think\console\Command;
use think\console\Input;
use think\console\Output;


class Leave extends Command
{
    //命令描述
    protected function configure()
    {
        $this->setName('leave')->setDescription('Leave');
    }

    protected function execute(Input $input, Output $output)
    {

        $redis = new RedisEx();

        $redis->setOption();

        $redis->psubscribe(array('__keyevent@0__:expired'), array($this, 'psubscribe'));//调用下面的psubscribe方法
    }

    /**
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * 业务逻辑代码在该方法执行
     */
    public function psubscribe($redis, $pattern, $chan, $msg)
    {

        //编写自己的逻辑代码

        var_dump($redis,$pattern,$chan,$msg);

       $info = \db('ceshi')->insert(['content'=>$msg]);       
        if ($info) {
            echo "请假:" . $msg . '成功!' . PHP_EOL;
        } else {
            echo "请假:" . $msg . '失败!' . PHP_EOL;
        }
    }
}

方便使用我们可以写成一个方法

<?php
namespace app\api\controller\v1;

use app\common\controller\Api;
// use app\common\model\Join;
// use app\common\model\SlowRide;
use think\Cache;
// use function Matrix\diagonal;

class Vote extends Api
{

    protected $noNeedLogin = ['lists', 'index', 'userDetail','slowRide','redisExMsg'];
    protected $noNeedRight = ['UserVote', 'ranking'];

   

    public function redisExMsg()
    {
        $redis = Cache::store('redis')->handler();
        $time = time();
        $redis->setEx($time, '5', 'R12324124124');
        $this->success('',$time);
    }
}


第四步:建了一个 “leave”命令,重点是execute()方法,redis的psubscribe监听 “0”这个数据库,有 key "expired"(过期)就执行后面的回调方法,在回调方法里可以使用curl方式调用写好的接口,功能逻辑有变动也不需要修改这里命令行的代码,$msg参数就是过期的键名,在我这里就应该是存放的是某个项目的id。

第四步:在项目根目录,先php think查看是有已有“leave”这个命令

然后在项目根目录执行leave命令

扩展资料:

1.打开CMD执行redis-cli后在执行 config set notify-keyspace-events Ex

2.打开CMD执行redis-cli,在执行PSUBSCRIBE __keyevent@0__:expired

3.打开CMD执行redis-cli,在执行setex t_key 2 t_value(也是是延迟两秒后执行)
https://blog.csdn.net/weixin_44006267/article/details/104406826

如图: