首页 Order Swoole4 正文

Swoole4 [协程客户端] Redis客户端

金鹏头像 金鹏 Swoole4 2021-12-26 16:12:43 0 819
导读:协程Redis客户端本客户端不再推荐使用,推荐使用Swoole\Runtime::enableCoroutine+phpredis或predis的方式,即一键协程化...

协程 Redis 客户端

本客户端不再推荐使用,推荐使用 Swoole\Runtime::enableCoroutine + phpredispredis 的方式,即一键协程化原生 PHPredis 客户端使用。

使用示例

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $val = $redis->get('key');
});

subscribe pSubscribe 无法用于 defer(true) 的情况。

方法

方法的使用基本与 phpredis 保持一致。

以下说明不同于 phpredis 的实现:

1、尚未实现的 Redis 命令:scan object sort migrate hscan sscan zscan

2、subscribe pSubscribe 的使用方式,无需设置回调函数;

3、序列化 PHP 变量的支持,在 connect() 方法的第三个参数设置为 true 时,开启序列化 PHP 变量特性,默认为 false

__construct()

Redis 协程客户端构造方法,可以设置 Redis 连接的配置选项,和 setOptions() 方法参数一致。

Swoole\Coroutine\Redis::__construct(array $options = null);

setOptions()

4.2.10 版本后新增了该方法,用于在构造和连接后设置 Redis 客户端的一些配置

该函数是 Swoole 风格的,需通过 Key-Value 键值对数组来配置

Swoole\Coroutine\Redis->setOptions(array $options): void
  • 可配置选项

key说明
connect_timeout连接的超时时间,默认为全局的协程 socket_connect_timeout(1 秒)
timeout超时时间,默认为全局的协程 socket_timeout,参考客户端超时规则
serialize自动序列化,默认关闭
reconnect自动连接尝试次数,如果连接由于超时等原因被 close 正常断开,下一次发起请求时,会自动尝试连接然后再发送请求,默认为 1 次 (true), 一旦失败指定次数后不会再继续尝试,需手动重连。该机制仅用于连接保活,不会重发请求导致不幂等接口出错等问题
compatibility_modehmGet/hGetAll/zRange/zRevRange/zRangeByScore/zRevRangeByScore 函数返回结果与 php-redis 不一致的兼容解决方案,开启之后 Co\Redisphp-redis 返回结果一致,默认关闭 【此配置项在 v4.4.0 或更高版本可用】

set()

存数据。

Swoole\Coroutine\Redis->set(string $key, mixed $value, array|int $option): bool
  • 参数

    • 功能:选项

    • 默认值:无

    • 其它值:无

    • 功能:数据内容【非字符串类型会自动序列化】

    • 默认值:无

    • 其它值:无

    • 功能:数据的 key

    • 默认值:无

    • 其它值:无

    • string $key

    • string $value

    • string $options

      $option 说明:
      整型:设置过期时间,如 3600
      数组:高级过期设置,如 ['nx', 'ex' => 10]['xx', 'px' => 1000]

      px: 表示毫秒级过期时间
      ex: 表示秒级过期时间
      nx: 表示不存在时设置超时
      xx: 表示存在时设置超时

request()

向 Redis 服务器发送一个自定义的指令。类似于 phpredis 的 rawCommand。

Swoole\Coroutine\Redis->request(array $args): void
  • 参数

    • 功能:参数列表,必须为数组格式参数。【第一个元素必须为 Redis 指令,其他的元素是指令的参数,底层会自动打包为 Redis 协议请求进行发送。】

    • 默认值:无

    • 其它值:无

    • array $args

  • 返回值

取决于 Redis 服务器对指令的处理方式,可能会返回数字、布尔型、字符串、数组等类型。

  • 使用示例

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379); // 若是本地UNIXSocket则host参数应以形如`unix://tmp/your_file.sock`的格式填写
    $res = $redis->request(['object', 'encoding', 'key1']);
    var_dump($res);
});

属性

errCode

错误代码。

错误代码说明
1Error in read or write
2Everything else...
3End of file
4Protocol error
5Out of memory

errMsg

错误消息。

connected

判断当前 Redis 客户端是否连接到了服务器。

常量

用于 multi($mode) 方法,默认为 SWOOLE_REDIS_MODE_MULTI 模式:

  • SWOOLE_REDIS_MODE_MULTI

  • SWOOLE_REDIS_MODE_PIPELINE

用于判断 type() 命令的返回值:

  • SWOOLE_REDIS_TYPE_NOT_FOUND

  • SWOOLE_REDIS_TYPE_STRING

  • SWOOLE_REDIS_TYPE_SET

  • SWOOLE_REDIS_TYPE_LIST

  • SWOOLE_REDIS_TYPE_ZSET

  • SWOOLE_REDIS_TYPE_HASH

事务模式

可使用 multiexec 实现 Redis 的事务模式。

  • 提示

    • 使用 mutli 指令启动事务,之后所有指令将被加入到队列中等待执行

    • 使用 exec 指令执行事务中的所有操作,并一次性返回所有结果

  • 使用示例

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    $redis->multi();
    $redis->set('key3', 'rango');
    $redis->get('key1');
    $redis->get('key2');
    $redis->get('key3');

    $result = $redis->exec();
    var_dump($result);
});

订阅模式

Swoole 版本 >= v4.2.13 可用,4.2.12 及以下版本订阅模式存在 BUG

订阅

phpredis 不同,subscribe/psubscribe 为协程风格。

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    if ($redis->subscribe(['channel1', 'channel2', 'channel3'])) // 或者使用psubscribe
    {
        while ($msg = $redis->recv()) {
            // msg是一个数组, 包含以下信息
            // $type # 返回值的类型:显示订阅成功
            // $name # 订阅的频道名字 或 来源频道名字
            // $info  # 目前已订阅的频道数量 或 信息内容
            list($type, $name, $info) = $msg;
            if ($type == 'subscribe') { // 或psubscribe
                // 频道订阅成功消息,订阅几个频道就有几条
            } else if ($type == 'unsubscribe' && $info == 0){ // 或punsubscribe
                break; // 收到取消订阅消息,并且剩余订阅的频道数为0,不再接收,结束循环
            } else if ($type == 'message') {  // 若为psubscribe,此处为pmessage
                var_dump($name); // 打印来源频道名字
                var_dump($info); // 打印消息
                // balabalaba.... // 处理消息
                if ($need_unsubscribe) { // 某个情况下需要退订
                    $redis->unsubscribe(); // 继续recv等待退订完成
                }
            }
        }
    }
});

退订

退订使用 unsubscribe/punsubscribe$redis->unsubscribe(['channel1'])

此时 $redis->recv() 将会接收到一条取消订阅消息,若取消订阅多个频道,则会收到多条。

注意:退订后务必继续 recv() 到收到最后一条取消订阅消息($msg[2] == 0),收到此条消息后,才会退出订阅模式

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->connect('127.0.0.1', 6379);
    if ($redis->subscribe(['channel1', 'channel2', 'channel3'])) // or use psubscribe
    {
        while ($msg = $redis->recv()) {
            // msg is an array containing the following information
            // $type # return type: show subscription success
            // $name # subscribed channel name or source channel name
            // $info  # the number of channels or information content currently subscribed
            list($type, $name, $info) = $msg;
            if ($type == 'subscribe') // or psubscribe
            {
                // channel subscription success message
            }
            else if ($type == 'unsubscribe' && $info == 0) // or punsubscribe
            {
                break; // received the unsubscribe message, and the number of channels remaining for the subscription is 0, no longer received, break the loop
            }
            else if ($type == 'message') // if it's psubscribe,here is pmessage
            {
                // print source channel name
                var_dump($name);
                // print message
                var_dump($info);
                // handle messsage
                if ($need_unsubscribe) // in some cases, you need to unsubscribe
                {
                    $redis->unsubscribe(); // continue recv to wait unsubscribe finished
                }
            }
        }
    }
});

兼容模式

Co\RedishmGet/hGetAll/zrange/zrevrange/zrangebyscore/zrevrangebyscore 指令返回结果与 phpredis 扩展返回值格式不一致的问题,已经得到解决 #2529

为了兼容老版本,在加上 $redis->setOptions(['compatibility_mode' => true]); 配置后,即可保证 Co\Redisphpredis 返回结果一致。

Swoole 版本 >= v4.4.0 可用

use Swoole\Coroutine\Redis;
use function Swoole\Coroutine\run;

run(function () {
    $redis = new Redis();
    $redis->setOptions(['compatibility_mode' => true]);
    $redis->connect('127.0.0.1', 6379);

    $co_get_val = $redis->get('novalue');
    $co_zrank_val = $redis->zRank('novalue', 1);
    $co_hgetall_val = $redis->hGetAll('hkey');
    $co_hmget_val = $redis->hmGet('hkey', array(3, 5));
    $co_zrange_val = $redis->zRange('zkey', 0, 99, true);
    $co_zrevrange_val = $redis->zRevRange('zkey', 0, 99, true);
    $co_zrangebyscore_val = $redis->zRangeByScore('zkey', 0, 99, ['withscores' => true]);
    $co_zrevrangebyscore_val = $redis->zRevRangeByScore('zkey', 99, 0, ['withscores' => true]);
});
本文地址:https://www.jinpeng.work/?id=88
若非特殊说明,文章均属本站原创,转载请注明原链接。
广告3

欢迎 发表评论:

  • 请填写验证码

日历

«    2025年4月    »
123456
78910111213
14151617181920
21222324252627
282930

控制面板

您好,欢迎到访网站!
  查看权限
广告2

退出请按Esc键