python redis模块_python redis 模块 官方文档(中)
Publish / Subscribe
redis-py包含一個PubSub對象,來訂閱頻道和監聽消息,創建PubSub對象很簡單
>>>?r?=?redis.StrictRedis(...)
>>>?p?=?r.pubsub()
一旦一個PubSub對象被創建,頻道channel和匹配模式(基于正則表達式的channel)就能夠訂閱了
>>>?p.subscribe('my-first-channel',?'my-second-channel',?...)
>>>?p.psubscribe('my-*',?...)
現在PubSub對象可以訂閱這些頻道了,可以從PubSub對象讀取消息來確認是否訂閱成功
>>>?p.get_message()
{'pattern':?None,?'type':?'subscribe',?'channel':?'my-second-channel',?'data':?1L}
>>>?p.get_message()
{'pattern':?None,?'type':?'subscribe',?'channel':?'my-first-channel',?'data':?2L}
>>>?p.get_message()
{'pattern':?None,?'type':?'psubscribe',?'channel':?'my-*',?'data':?3L}
從PubSub對象讀取的消息時一個包含一下鍵的字典
type:可以是以下值中的一個
‘subscribe’, ‘unsubscribe’, ‘psubscribe’, ‘punsubscribe’, ‘message’, ‘pmessage’
channel:訂閱或取消訂閱的頻道或者消息要發送的頻道
pattern: 匹配一個信息頻道的模式,除了'pmessage'其他情況下都是none
data:消息數據,對于(非)訂閱消息,這個值會是當前訂閱的channel和匹配模式連接的數量,對于[p]message,這個值就是發送的消息
現在就可以發送消息了
發送方法返回channel匹配和模型pattern匹配的數量
#?'my-first-channel'?匹配?'my-first-channel'?channel訂閱和'my-*'?pattern訂閱
#所以這些消息會被傳送給2個channel或pattern
>>>?r.publish('my-first-channel',?'some?data')
2
>>>?p.get_message()
{'channel':?'my-first-channel',?'data':?'some?data',?'pattern':?None,?'type':?'message'}
>>>?p.get_message()
{'channel':?'my-first-channel',?'data':?'some?data',?'pattern':?'my-*',?'type':?'pmessage'}
對于取消訂閱,和訂閱一樣,如果沒有傳遞參數,會取消所有訂閱
>>>?p.unsubscribe()
>>>?p.punsubscribe('my-*')
>>>?p.get_message()
{'channel':?'my-second-channel',?'data':?2L,?'pattern':?None,?'type':?'unsubscribe'}
>>>?p.get_message()
{'channel':?'my-first-channel',?'data':?1L,?'pattern':?None,?'type':?'unsubscribe'}
>>>?p.get_message()
{'channel':?'my-*',?'data':?0L,?'pattern':?None,?'type':?'punsubscribe'}
redis-py 也允許你注冊一個回調功能來控制消息發布.消息控制器只有一個參數,message,就像上面例子一樣是一個字典.用消息控制器訂閱頻道channel或者匹配樣式pattern,傳送channel或pattern作為關鍵字參數,值作為回調功能
當使用消息控制器從channel或pattern讀取消息時,消息字典被創建并傳遞給消息控制器.這種情況下,由于消息已經被處理,get_message()返回一個None值
>>>?def?my_handler(message):
...?????print?'MY?HANDLER:?',?message['data']
>>>?p.subscribe(**{'my-channel':?my_handler})
#?讀取訂閱確認信息
>>>?p.get_message()
{'pattern':?None,?'type':?'subscribe',?'channel':?'my-channel',?'data':?1L}
>>>?r.publish('my-channel',?'awesome?data')
1
#由于消息控制器的作用,我們需要告訴實例讀取數據,可以有多種方式處理,
#這里我們只使用get_message()
>>>?message?=?p.get_message()
MY?HANDLER:??awesome?data
#注意這里my_handler回調打印了上面的字符串
#?`message`是?None?因為消息被控制器控制了
>>>?print?message
None
如果你的應用不關心訂閱/取消訂閱確認消息(有時候是噪音),你可以傳一個ignore_subscribe_messages=True給r.pubsub().這會引起所有的訂閱非訂閱消息讀取,但不會出現在你的應用中
>>>?p?=?r.pubsub(ignore_subscribe_messages=True)
>>>?p.subscribe('my-channel')
>>>?p.get_message()
#隱藏了訂閱消息,返回None
>>>?r.publish('my-channel')
1
>>>?p.get_message()
{'channel':?'my-channel',?data':?'my?data',?'pattern':?None,?'type':?'message'}
有三種不同的讀取消息的策略
上面的例子使用pubsub.get_message().在這種場景,get_message()使用系統的'select'模式快速測試連接的socket.如果有數據可以被讀取,get_message()會讀取它,處理后返回或者傳遞給消息處理器.如果沒有數據讀取,get_message()會立刻返回None.這使得整合到你的應用中一個已存的事件循環并不重要
>>>?while?True:
>>>?????message?=?p.get_message()
>>>?????if?message:
>>>????????#?do?something?with?the?message
>>>?????time.sleep(0.001)??#?be?nice?to?the?system?:)
redis-py更老的版本只能用pubsub.listen()讀取消息,listen()是一個生成器,會阻塞直到有消息可以獲得.如果你的應用不需要做任何事除了從redis接收消息,并對消息做出反應,listen()是一個簡單的運行方式
>>>?for?message?in?p.listen():...?????#?do?something?with?the?message
第三種選擇是在單獨的線程里運行一個事件循環,pubsub.run_in_thread()創建一個新的線程并啟動事件循環.線程對象被返回給調用者run_in_thread().調用者可以使用thread.stop()來關閉事件循環和線程.在這種場景下,運行線程的只是一個簡單的對get_message()的包裝器,尤其是你創建一個小的非阻塞的事件循環.run_in_thread()有一個可選擇的sleep_time參數.如果被指定,事件循環會在每次循環迭代時用指定的值調用time.sleep()
注意,由于我們運行了一個單獨的線程,沒有辦法控制不是由注冊的消息控制器自動控制的消息.因此,如果你正在訂閱沒有消息控制器關聯的pattern或channel,redis-p會阻止你調用run_in_thread()
>>>?p.subscribe(**{'my-channel':?my_handler})
>>>?thread?=?p.run_in_thread(sleep_time=0.001)
#?現在事件循環在后臺運行處理消息
#?當要關閉該線程時
>>>?thread.stop()
一個PubSub對象綁定到同樣編碼的語義作為它創建的客戶端實例.任何采用unicode的pattern和channel在發給Redis之前會被編碼為指定的字符集.如果客戶端的解碼flagdecode_responses被設定為False(默認值),消息字典中的‘channel’, ‘pattern’ 和 ‘data’會變成byte字符串((Python 2時str, ?Python 3時byte).如果客戶端decode_responses是True,‘channel’, ‘pattern’ 和 ‘data’值會使用客戶端的字符集自動解碼為unicode字符
PubSub對象保存了他們訂閱的channel和pattern.在無法連接的事件中,如網絡錯誤或超時,當重新連接時PubSub對象會重新訂閱所有的先前的channel和pattern.無法連接期間發布的消息無法再呈現.當你要結束一個PubSub對象時,調用close()方法關閉連接
>>>?p?=?r.pubsub()
>>>?...
>>>?p.close()
總結
以上是生活随笔為你收集整理的python redis模块_python redis 模块 官方文档(中)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 华为手机没有耳塞插口_鸿蒙OS 2.0手
- 下一篇: websocket python爬虫_p