PHP使用Redis的Pub/Sub(发布订阅)命令

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 本篇笔记简单介绍了Redis的Pub/Sub的概念和php使用rawCommand命令和php-redis扩展方法实现publish/subscribe发布/订阅

1.概念

名称 含义
channel 频道:生产者和消费者直接操作的对象
publish 生产者:向channel发送消息
subscribe 消费者:订阅一个或多个channel
psubscribe 消费者:匹配订阅一个或多个channel
punsubscribe 退订:匹配退订,无参数则退订全部channel
unsubscribe 退订:退订指定的channel,无参数则退订全部channel
pubsub 列出当前活动channel(至少有一个订阅)

2.注意事项

1.生产者publish消息时打开一个连接,publish后连接可以立即关闭
2.channel只接收publish发送的消息,自身不存储消息,如果channel没有被订阅,则消息丢弃
3.订阅的消费者需要一直在线,阻塞获取消息,连接断开表示立即退订

3.使用rawCommand命令实现发布订阅

rawCommand是php-redis扩展中提供的命令,可以向redis发送任何原生的命令
1.消费者订阅Subscribe.php
消费者需要创建redis长连接,并且设置set_time_limit和default_socket_timeout,以确保阻塞获取消息过程php不超时,socket连接不超时

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/23
 * Time: 11:29
 */
//设置php脚本执行时间
set_time_limit(0);
//设置socket连接超时时间
ini_set('default_socket_timeout', -1);
//声明测试频道名称
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
try {
    $redis = new Redis();
    //建立一个长链接
    $redis->pconnect('192.168.75.132', 6379);
    //阻塞获取消息
    while (true){
        //构建命令参数
        $param = array('subscribe', $channelName, $channelName2);
        //使用call_user_func_array回调执行命令
        $ret = call_user_func_array(array($redis, 'rawCommand'), $param);
        //如果结果是消息结构
        if (isset($ret[0]) && $ret[0] == 'message'){
            //输出消息频道和消息内容
            echo "channel:".$ret[1].",message:".$ret[2]."\n";
        } else {
            //没有消息休眠1秒
            sleep(1);
        }
    }
} catch (Exception $e){
    echo $e->getMessage();
}

2.生产者发送消息Publish.php

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/23
 * Time: 11:59
 */
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
//向指定频道发送消息
try {
    $redis = new Redis();
    $redis->connect('192.168.75.132', 6379);
    for ($i=0;$i<5;$i++){
        $data = array('key' => 'key'.$i, 'data' => 'testdata');
        $param = array('publish', $channelName, json_encode($data));
        $ret = call_user_func_array(array($redis, 'rawCommand'), $param);
        print_r($ret);
    }
} catch (Exception $e){
    echo $e->getMessage();
}

3.执行消费者订阅,开始阻塞获取消息php Subscribe.php
4.执行生产者,开始发送消息php Publish.php

php .\Publish.php
22222
#返回执行结果:频道的订阅数量

查看消费者终端

php .\Subscribe.php
channel:testPubSub,message:{"key":"key0","data":"testdata"}
channel:testPubSub,message:{"key":"key1","data":"testdata"}
channel:testPubSub,message:{"key":"key2","data":"testdata"}
channel:testPubSub,message:{"key":"key3","data":"testdata"}
channel:testPubSub,message:{"key":"key4","data":"testdata"}

消费者获取到了生产者发送的消息。

4.直接使用php-redis扩展提供的方法实现发布订阅

1.消费者订阅Subscribe.php

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/23
 * Time: 11:29
 */
//设置php脚本执行时间
set_time_limit(0);
//设置socket连接超时时间
ini_set('default_socket_timeout', -1);
//声明测试频道名称
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
try {
    $redis = new Redis();
    //建立一个长链接
    $redis->pconnect('192.168.75.132', 6379);
    //阻塞获取消息
    $redis->subscribe(array($channelName, $channelName2), function ($redis, $chan, $msg){
        echo "channel:".$chan.",message:".$msg."\n";
    });
} catch (Exception $e){
    echo $e->getMessage();
}

2.生产者发送消息Publish.php

<?php
/**
 * Created by PhpStorm.
 * User: jmsite.cn
 * Date: 2019/1/23
 * Time: 11:59
 */
$channelName = "testPubSub";
$channelName2 = "testPubSub2";
//向指定频道发送消息
try {
    $redis = new Redis();
    $redis->connect('192.168.75.132', 6379);
    for ($i=0;$i<5;$i++){
        $data = array('key' => 'key'.$i, 'data' => 'testdata');
        $ret = $redis->publish($channelName, json_encode($data));
        print_r($ret);
    }
} catch (Exception $e){
    echo $e->getMessage();
}

3.执行消费者订阅,开始阻塞获取消息php Subscribe.php
4.执行生产者,开始发送消息php Publish.php

php .\Publish.php
22222
#返回执行结果:频道的订阅数量

查看消费者终端

php .\Subscribe.php
channel:testPubSub,message:{"key":"key0","data":"testdata"}
channel:testPubSub,message:{"key":"key1","data":"testdata"}
channel:testPubSub,message:{"key":"key2","data":"testdata"}
channel:testPubSub,message:{"key":"key3","data":"testdata"}
channel:testPubSub,message:{"key":"key4","data":"testdata"}

消费者同样获取到了生产者发送的消息。
退订和查看活动channel命令与生产者和消费者类似,只是参数不同而已。

原文地址: https://www.jmsite.cn/blog-586.html

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
NoSQL Redis
Redis 发布订阅
10月更文挑战第18天
33 1
Redis 发布订阅
|
1月前
|
存储 NoSQL PHP
PHP与Redis结合使用,提升数据存储性能
随着互联网应用的发展,PHP与Redis的结合成为提升数据存储性能的重要手段。PHP作为流行的服务器端语言,常用于网站开发;Redis作为高性能内存数据库,以其快速读写能力,有效优化数据访问速度,减轻数据库压力。两者结合通过缓存机制显著提升应用响应速度,支持高并发场景下的稳定性和可扩展性。
|
1月前
|
存储 NoSQL 关系型数据库
PHP 使用 Redis
10月更文挑战第22天
34 6
|
2月前
|
NoSQL Java Redis
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
这篇文章介绍了Redis的基本命令,并展示了如何使用Netty框架直接与Redis服务器进行通信,包括设置Netty客户端、编写处理程序以及初始化Channel的完整示例代码。
60 1
redis的基本命令,并用netty操作redis(不使用springboot或者spring框架)就单纯的用netty搞。
|
1月前
|
存储 NoSQL Java
Redis命令:列表模糊删除详解
通过本文的介绍,我们详细探讨了如何在Redis中实现列表的模糊删除。虽然Redis没有直接提供模糊删除命令,但可以通过组合使用 `LRANGE`和 `LREM`命令,并在客户端代码中进行模糊匹配,来实现这一功能。希望本文能帮助你在实际应用中更有效地操作Redis列表。
39 0
|
2月前
|
tengine 应用服务中间件 Linux
Tengine、Nginx安装PHP命令教程
要在阿里云Linux上安装PHP,请先更新YUM源并启用PHP 8.0仓库,然后安装PHP及相关扩展。通过`php -v`命令验证安装成功后,需修改Nginx配置文件以支持PHP,并重启服务。最后,创建`phpinfo.php`文件测试安装是否成功。对于CentOS系统,还需安装EPEL源和Remi仓库,其余步骤类似。完成上述操作后,可通过浏览器访问`http://IP地址/phpinfo.php`测试安装结果。
|
2月前
|
缓存 NoSQL 测试技术
Redis如何解决频繁的命令往返造成的性能瓶颈!
Redis如何解决频繁的命令往返造成的性能瓶颈!
|
2月前
|
缓存 NoSQL Redis
Redis命令:列表模糊删除详解
Redis命令:列表模糊删除详解
70 3
|
2月前
|
NoSQL 关系型数据库 MySQL
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
本文全面阐述了Redis事务的特性、原理、具体命令操作,指出Redis事务具有原子性但不保证一致性、持久性和隔离性,并解释了Redis事务的适用场景和WATCH命令的乐观锁机制。
318 0
Redis 事务特性、原理、具体命令操作全方位诠释 —— 零基础可学习
|
2月前
|
NoSQL Redis 数据安全/隐私保护
Redis 命令
10月更文挑战第15天
31 0