美文网首页
Redis学习笔记:订阅和发布

Redis学习笔记:订阅和发布

作者: 马谦马谦马谦 | 来源:发表于2017-12-04 21:13 被阅读0次

    原文链接:Redis学习笔记:订阅和发布

    一、基本使用

    除了任务队列以外,redis还有一种基于“发布/订阅”模式的消息传递,它能让消息在多个频道以及多个客户端之间进行消息传递。

    1.1 发布

    向频道发布消息使用命令PUBLISH channel message

    redis > publish chan1 hello
    (integer) 0
    

    消息发送成功后,将会返回一个整数,表示收到这条消息的订阅者数量,本例中的0即表示当前没有用户订阅该频道。消息发布后不会被持久化,如果客户端当前没有订阅该频道,后续再订阅也不会收到订阅前的消息。

    1.2 订阅

    订阅频道使用命令SUBSCRIBE channel

    redis > subscribe chan1  
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "chan1"
    3) (integer) 1
    

    订阅后会返回一个subcribe类型的消息,该消息包含三行,第一行为subcribe表示订阅成功,第二行chann1是订阅的频道名,第三行是当前客户端订阅的频道数量。

    此时客户端将进入订阅模式,使用redis-cli终端时该命令会阻塞,第三方客户端中也只能输入SUBSCRIBE UNSUBSCRIBE PSUBSCRIBE PUNSUBSCRIBE 这四个属于“发布/订阅”模式的命令。如果再使用PUBLISH chann1 hellochann1发布消息,订阅者就会收到消息:

    1) "message"
    2) "chan1"
    3) "hello"
    

    消息有三个值,第一个值message表示这是一条消息,和上面的subcribe区分。第二个值表示消息的来源频道名,第三个值是消息的内容。

    1.3 取消订阅

    取消订阅使用命令UNSUBSCRIBE [channel ...],带上频道名取消特定频道,默认取消所有频道。

    由于redis-cli在订阅后会阻塞,无法手动输入取消订阅命令,如果要取消订阅使用Ctrl-C退出即可。在第三方客户端例如python或者其他程序语言客户端中要取消订阅,需要进行subscribe操作。

    二、PSUBSCRIBE和PUNSUBSCRIBE

    psubscribepunsubscribe命令和上面的两个命令类似,只是这两个命令允许频道名使用通配符参数,例如psubscribe chan?将会订阅类似chan1 chan2 chan3...的频道:

    redis > psubscribe chan?
    Reading messages... (press Ctrl-C to quit)
    1) "psubscribe"  # 订阅
    2) "chan?"  # 订阅的频道
    3) (integer) 1  # 当前订阅的频道
    

    这里的返回值和subscribe命令一致,只是在收到消息后会多出一个值:

    1) "pmessage"  # 消息类型
    2) "chan?"  # 订阅的频道规则
    3) "chan1"  # 实际的频道
    4) "abc"  # 消息的内容
    

    psubscribe可以重复订阅频道,订阅后将会显示实际订阅的频道信息:

    redis > psubscribe chan1 chan?
    Reading messages... (press Ctrl-C to quit)
    1) "psubscribe"
    2) "chan1"
    3) (integer) 1
    1) "psubscribe"
    2) "chan?"
    3) (integer) 2
    

    此时,发布一则消息订阅者将会接收多次,次数根据订阅规则数量的不同而不同。同时,发布者此时也会显示有多个订阅者接收到了这条消息:

    # 发布者
    127.0.0.1:6379> publish chan1 abc  # 发送消息
    (integer) 2  # 有两个订阅者收到了消息
    
    # 订阅者
    1) "pmessage"  # 第一条消息
    2) "chan1"
    3) "chan1"
    4) "abc"
    1) "pmessage"  # 第二条消息
    2) "chan?"  # 订阅规则
    3) "chan1"  # 实际接收的频道
    4) "abc"
    

    最有有一个要注意的点是:使用psubscribe订阅的频道只能使用punsubscribe命令取消订阅。

    三、python代码实现订阅发布

    3.1 发布者代码

    # -*- coding: utf8 -*-
    
    """
    订阅者代码
    """
    
    import redis
    
    
    def subscribe(conn):
        pub_sub = conn.pubsub()
        pub_sub.subscribe(["chan"])
        i = 0
        for item in pub_sub.listen():  # 循环监听订阅消息
            print item
            i += 1
            if i == 2:
                pub_sub.unsubscribe()  # 取消订阅
            elif i == 3:  # 退出监听
                print "exit"
                break
    
    
    if __name__ == "__main__":
        conn = redis.StrictRedis()
        subscribe(conn)
    

    3.2 订阅者代码

    # -*- coding:utf8 -*-
    
    """
    发布者
    """
    
    import redis
    
    
    def publish(conn):
        for i in range(5):
            conn.publish("chan", i)  # 发布消息
    
    
    if __name__ == "__main__":
        conn = redis.StrictRedis()
        publish(conn)
    

    3.3 结果

    先运行订阅者,将会先打印一条订阅的消息:

    {'pattern': None, 'type': 'subscribe', 'channel': 'chan', 'data': 1L}
    

    然后运行发布者代码,订阅者输出:

    {'pattern': None, 'type': 'subscribe', 'channel': 'chan', 'data': 1L}
    {'pattern': None, 'type': 'message', 'channel': 'chan', 'data': '0'}
    {'pattern': None, 'type': 'message', 'channel': 'chan', 'data': '1'}
    exit
    

    3.4 问题

    根据书上的描述,在取消订阅后将会收到一条取消订阅的消息:

    {'pattern': None, 'type': 'unsubscribe', 'channel': 'chan', 'data': 0L}
    

    但是这里并没有收到,很奇怪,不知道是不是版本的原因,暂且把问题放在这里吧。

    相关文章

      网友评论

          本文标题:Redis学习笔记:订阅和发布

          本文链接:https://www.haomeiwen.com/subject/lmjfixtx.html