Redis 发布订阅 (pub/sub) 是一种消息通信模式:
发布者 (pub) 发送消息到频道,订阅者 (sub) 从频道接收消息
Redis 客户端可以订阅任意数量的频道,同样地,频道可以有任意数量的订阅者
发布者和订阅者无耦合关系,互相单独存在
举个例子:
# 启动一个客户端,加上 --raw 选项以便接收中文消息时正常显示
mcdx@ubuntu:~$ redis-cli --raw # 取名为 1 号客户端
127.0.0.1:6379> subscribe ch1 ch2 # 创建并订阅两个频道
subscribe
ch1
1
subscribe
ch2
2
打开另一个客户端:
mcdx@ubuntu:~$ redis-cli # 取名为 2 号客户端
127.0.0.1:6379> publish ch1 今天天气不错 # 向频道 ch1 发送消息
(integer) 1
此时 1 号客户端收到消息:
mcdx@ubuntu:~$ redis-cli --raw
127.0.0.1:6379> subscribe ch1 ch2
subscribe
ch1
1
subscribe
ch2
2
message
ch1
今天天气不错
试一下用 ipython 发送消息:
In [1]: import redis # 引入 redis
In [2]: r = redis.StrictRedis(host='localhost') # 创建客户端
In [3]: r.publish('ch2', '是啊,确实不错,天天下雨') # 向频道 ch2 发送消息
Out[3]: 1
此时 1 号客户端的状态:
mcdx@ubuntu:~$ redis-cli --raw
127.0.0.1:6379> subscribe ch1 ch2
subscribe
ch1
1
subscribe
ch2
2
message
ch1
今天天气不错
message
ch2
是啊,确实不错,天天下雨
现在,让 ipython 也接收消息:
In [1]: import redis
In [2]: r = redis.StrictRedis(host='localhost')
In [3]: r.publish('ch2', '是啊,确实不错,天天下雨')
Out[3]: 1
# 需要先来这么一步,跟 redis-cli 不同,这个 p 叫发布订阅系统
In [4]: p = r.pubsub()
In [5]: p.subscribe('ch2') # 订阅 ch2 频道
In [6]: for msg in p.listen(): # 监听这个频道
...: print(msg)
...:
{'data': 1, 'pattern': None, 'type': 'subscribe', 'channel': b'ch2'}
2 号客户端发送消息:
mcdx@ubuntu:~$ redis-cli
127.0.0.1:6379> publish ch1 今天天气不错
(integer) 1
127.0.0.1:6379> publish ch2 Redis还真是不简单 # 两个客户端将接收此消息
(integer) 2
1 号客户端的状态:
mcdx@ubuntu:~$ redis-cli --raw
127.0.0.1:6379> subscribe ch1 ch2
subscribe
ch1
1
subscribe
ch2
2
message
ch1
今天天气不错
message
ch2
是啊,确实不错,天天下雨
message
ch2
Redis还真是不简单 # 接收到消息
ipython 的状态:
In [1]: import redis
In [2]: r = redis.StrictRedis(host='localhost')
In [3]: r.publish('ch2', '是啊,确实不错,天天下雨')
Out[3]: 1
In [4]: p = r.pubsub()
In [5]: p.subscribe('ch2')
In [6]: for msg in p.listen():
...: print(msg) # 看来 msg 是字典
...:
{'data': 1, 'pattern': None, 'type': 'subscribe', 'channel': b'ch2'}
{'data': b'Redis\xe8\xbf\x98\xe7\x9c\x9f\xe6\x98\xaf\xe4\xb8\x8d...',
'pattern': None, 'type': 'message', 'channel': b'ch2'} # 接收到消息
ipython 接收消息后显示中文有困难,处理一下:
In [9]: for msg in p.listen():
...: print(msg['data'].decode('utf-8')) # 只打印 msg 的 data 的值
...:
2 号客户端再发一条消息:
mcdx@ubuntu:~$ redis-cli
127.0.0.1:6379> publish ch1 今天天气不错
(integer) 1
127.0.0.1:6379> publish ch2 Redis还真是不简单
(integer) 2
127.0.0.1:6379> publish ch2 再来一条 # 发送消息
(integer) 2
1 号客户端的状态:
mcdx@ubuntu:~$ redis-cli --raw
127.0.0.1:6379> subscribe ch1 ch2
subscribe
ch1
1
subscribe
ch2
2
message
ch1
今天天气不错
message
ch2
是啊,确实不错,天天下雨
message
ch2
Redis还真是不简单
message
ch2
再来一条 # 接收消息
ipython 的状态:
In [9]: for msg in p.listen():
...: print(msg['data'].decode('utf-8'))
...:
再来一条 # 接收消息
网友评论