Redis-pub-sub-python

Redis Pub/Sub

一.定义 pubsub指的是发布者将消息发布到指定通道,并不清楚(或者说不关心)订阅者,同时订阅者也指定接收通道接收消息,并不关心具体的发布者。通过这样的方法,实现发布者和订阅者之间的解耦。

二.Redis原语

1.订阅channe1到channel3的三个频道:

subscribe channel1 channel2 channel3

2.向channel1发布消息"hello_world":

publish channel1 "hello_world"

3.channel1接收消息格式:

message channel1 REAL_MESSAGE

其中第一项是消息类别,第二项是频道名称,第三项是实际接收的消息

4.unsubscribe结束对所有频道的订阅,在客户端调用

5.pattern-matching pub/sub 根据正则做消息订阅,接收所有以news开头频道的消息:

psubscribe news 如果这里用的是subscribe,那么只能接收到名为"news“频道的消息,而不是以news开头所有频道的消息。

三.python版本实现

1.pubilsh.py 实现发布的功能是比较简单的(当然也是在原型条件下,没有考虑接收者的消息反馈和重发),代码基本只有三行:

import redis

r = redis.Redis(host='localhost')
r.publish('ch1', 'hello world')

这里publish的返回值是当前这个频道subscribe的数量

2.阻塞subscribe.py 实现阻塞版本的消息接收需要使用listen函数:

import redis

r = redis.Redis(host='localhost')
pubsub = r.pubsub()
pubsub.subscribe('ch1')

for item in pubsub.listen():
    print item

如果需要实现轮询的效果,可以在for外面再套一层while循环;listen的返回值格式如下:

{'pattern': None, 'type': 'message', 'channel': 'ch1', 'data': 'hello,wolrd'}

其中有效部分为item[“data”]。

3.非阻塞subscribe.py 在subscribe的接口层面,这是不成立的,但是可以在语言层面通过多线程实现:独立的线程负责接收接口消息,主线程可以做自己的事情。

import redis
import threading
import time

def subscriber():
    r = redis.Redis(host='localhost')
    sub = r.pubsub()
    sub.subscribe('a1')
    while True:
        for item in sub.listen():
            print item


if __name__ == '__main__':

    t = threading.Thread(target=subscriber)
    t.setDaemon(True)
    t.start()
    while 1:
        print 'waiting'
        time.sleep(10)