文档章节

Python client for Redis 官翻文档2.10.1(四)

山下狮子
 山下狮子
发布于 2014/06/21 14:44
字数 1670
阅读 290
收藏 0

Publish / Subscribe

发布/订阅

redis-py includes a PubSub object that subscribes to channels and listens for new messages. Creating a PubSub object is easy.

redis-py包含一个订阅监听信息的PubSub对象。创建PubSub对象非常简单。

>>> r = redis.StrictRedis(...)
>>> p = r.pubsub()

Once a PubSub instance is created, channels and patterns can be subscribed to.

一旦建立成功,就可以使用subscribe  和 psubscribe就可以使用了。

>>> p.subscribe('my-first-channel', 'my-second-channel', ...)
>>> p.psubscribe('my-*', ...)

The PubSub instance is now subscribed to those channels/patterns. The subscription confirmations can be seen by reading messages from the PubSub instance.

PubSub实例现在就可以订阅了。通过PubSub实例的get_message可以查看订阅信息

>>> 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}

Every message read from a PubSub instance will be a dictionary with the following keys.

每个message 都是一个字典,包含下面的keys

  • type: One of the following: 'subscribe', 'unsubscribe', 'psubscribe', 'punsubscribe', 'message', 'pmessage'

     'subscribe', 'unsubscribe', 'psubscribe', 'punsubscribe', 'message', 'pmessage'这四个,看完redis的命令,应该知道的

  • channel: The channel [un]subscribed to or the channel a message was published to

    订阅的频道

  • pattern: The pattern that matched a published message's channel. Will be None in all cases except for 'pmessage' types.

    模式匹配发布消息的通道,除了是pmessage类型,其它都是None

  • data: The message data. With [un]subscribe messages, this value will be the number of channels and patterns the connection is currently subscribed to. With [p]message messages, this value will be the actual published message.

    这个data不是实际数据,是当前的频道是第几频道

看具体执行比较容易明白:

import redis

r = redis.StrictRedis(host="127.0.0.1",port=6379,db=0)

p = r.pubsub()

p.subscribe('my-first-channel','channel2')

r.publish('my-first-channel', 'some data')

r.publish('channel2', 'some data2')

print p.get_message()

print p.get_message()

print p.get_message()

print p.get_message()


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

{'pattern': None, 'type': 'subscribe', 'channel': 'my-first-channel', 'data': 2L}

{'pattern': None, 'type': 'message', 'channel': 'my-first-channel', 'data': 'some data'}

{'pattern': None, 'type': 'message', 'channel': 'channel2', 'data': 'some data2'}



Let's send a message now.

开始发布信息

# the publish method returns the number matching channel and pattern返回订阅此频道的数量
# subscriptions. 'my-first-channel' matches both the 'my-first-channel'
#订阅  ‘my-first-channel’  频道和 订阅 ‘my-* '都会匹配 my-first-channel
# subscription and the 'my-*' pattern subscription, so this message will
# be delivered to 2 channels/patterns
>>> 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'}

Unsubscribing works just like subscribing. If no arguments are passed to [p]unsubscribe, all channels or patterns will be unsubscribed from.

Unsubscribing和subscribing类似。如果没有参数,取消所有的订阅

>>> 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 also allows you to register callback functions to handle published messages. Message handlers take a single argument, the message, which is a dictionary just like the examples above. To subscribe to a channel or pattern with a message handler, pass the channel or pattern name as a keyword argument with its value being the callback function.

redis-py允许我们注册一个回调函数处理发布的信息。

看下面例子

When a message is read on a channel or pattern with a message handler, the message dictionary is created and passed to the message handler. In this case, a None value is returned from get_message() since the message was already handled.

看下面例子(这个例子跟我在电脑上的运行有差别,不知道为什么)

官方的例子:

>>> def my_handler(message):
...     print 'MY HANDLER: ', message['data']
>>> p.subscribe(**{'my-channel': my_handler})# read the subscribe confirmation message
>>> p.get_message()
{'pattern': None, 'type': 'subscribe', 'channel': 'my-channel', 'data': 1L}

>>> r.publish('my-channel', 'awesome data')
1
# for the message handler to work, we need tell the instance to read data.
# this can be done in several ways (read more below). we'll just use
# the familiar get_message() function for now
>>> message = p.get_message()
MY HANDLER:  awesome data
# note here that the my_handler callback printed the string above.
# `message` is None because the message was handled by our handler.
>>> print messageNone

我电脑上的例子:

r = redis.StrictRedis(host="127.0.0.1",port=6379,db=0)

p = r.pubsub()

def my_handler(message):

     print 'MY HANDLER: ', message['data']


p.subscribe(**{'my-channel': my_handler})

r.publish('my-channel', 'awesome data')

print p.get_message()

print p.get_message()

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

MY HANDLER:  awesome data

None


If your application is not interested in the (sometimes noisy) subscribe/unsubscribe confirmation messages, you can ignore them by passing ignore_subscribe_messages=True to r.pubsub(). This will cause all subscribe/unsubscribe messages to be read, but they won't bubble up to your application.

如果对subscribe/unsubscribe确认信息不感兴趣,可以设置忽略。

>>> 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'}

There are three different strategies for reading messages.

有三种不同的策略针对message

The examples above have been using pubsub.get_message(). Behind the scenes, get_message() uses the system's 'select' module to quickly poll the connection's socket. If there's data available to be read, get_message() will read it, format the message and return it or pass it to a message handler. If there's no data to be read, get_message() will immediately return None. This makes it trivial to integrate into an existing event loop inside your application.

上面的例子使用pubsub.get_message()。在幕后,get_messge()使用系统的‘select’模块快速查看socket连接。如果有数据可以读将会读,格式化消息并返回,或传递到一个message handler.如果没有数据,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 :)

Older versions of redis-py only read messages with pubsub.listen(). listen() is a generator that blocks until a message is available. If your application doesn't need to do anything else but receive and act on messages received from redis, listen() is an easy way to get up an running.

老版本的redis-dy读取message使用pubsub.listen()方法。它是一个生成器直到返回信息。如果您的应用程序不需要做任何事情除了收到redis接收和处理消息

>>> for message in p.listen():
...     # do something with the message

The third option runs an event loop in a separate thread. pubsub.run_in_thread() creates a new thread and starts the event loop. The thread object is returned to the caller of run_in_thread(). The caller can use the thread.stop() method to shut down the event loop and thread. Behind the scenes, this is simply a wrapper around get_message() that runs in a separate thread, essentially creating a tiny non-blocking event loop for you. run_in_thread() takes an optional sleep_time argument. If specified, the event loop will call time.sleep() with the value in each iteration of the loop.


Note: Since we're running in a separate thread, there's no way to handle messages that aren't automatically handled with registered message handlers. Therefore, redis-py prevents you from calling run_in_thread() if you're subscribed to patterns or channels that don't have message handlers attached.

>>> p.subscribe(**{'my-channel': my_handler})
>>> thread = p.run_in_thread(sleep_time=0.001)
# the event loop is now running in the background processing messages
# when it's time to shut it down
...
>>> thread.stop()

A PubSub object adheres to the same encoding semantics as the client instance it was created from. Any channel or pattern that's unicode will be encoded using the charset specified on the client before being sent to Redis. If the client's decode_responses flag is set the False (the default), the 'channel', 'pattern' and 'data' values in message dictionaries will be byte strings (str on Python 2, bytes on Python 3). If the client's decode_responses is True, then the 'channel', 'pattern' and 'data' values will be automatically decoded to unicode strings using the client's charset.

PubSub objects remember what channels and patterns they are subscribed to. In the event of a disconnection such as a network error or timeout, the PubSub object will re-subscribe to all prior channels and patterns when reconnecting. Messages that were published while the client was disconnected cannot be delivered. When you're finished with a PubSub object, call its .close() method to shutdown the connection.

PubSub对象记住他们订阅渠道和模式。在网络断开的情况下,比如错误或超时,重新连接时,PubSub对象会重新订阅之前所有渠道和模式,消息发布客户端断开连接时不能交付。当你完成了一个PubSub对象,调用它的.close()方法来关闭连接。

>>> p = r.pubsub()
>>> ...
>>> p.close()


© 著作权归作者所有

山下狮子
粉丝 24
博文 115
码字总数 58167
作品 0
东城
程序员
私信 提问
Python client for Redis 官翻文档2.10.1(一)

Python client for Redis key-value store redis针对python的客户端, github地址:https://github.com/andymccurdy/redis-py/ 安装: 虽然称redis的python客户端称为redis-py,实际安装时的......

山下狮子
2014/06/19
1K
0
Python client for Redis 官翻文档2.10.1(二)

更多的细节 连接池: 在幕后,redis-py 使用连接池管理连接到redis-server的连接.默认, 一旦你创建了一个Redis的实例 ,这个实例相应有自己的连接池。你可以重写此行为,在创建一个Redis实例...

山下狮子
2014/06/20
565
0
Python client for Redis 官翻文档2.10.1(三)

Pipelines 管道 管道是Redis的子类,它支持缓冲多个命令,一次性发送到服务器去执行。可以大大的提高性能,减少服务器到客户端之间的TCP来回数据包。 管道的简单使用: >>> r = redis.Redis(....

山下狮子
2014/06/20
1K
0
jumpserver跳板机安装与配置实战

jumpserver安装与配置 参考jumpserver官网http://docs.jumpserver.org/zh/docs/stepbystep.html 一、准备python3和python虚拟环境 1.1安装依赖包 yum -y install wget sqlite-devel xz gcc ......

jxzhfei
2018/08/15
0
0
Sentry-Bug追踪系统安装.

Sentry安装 本文主要介绍在centos7 下通过docker安装sentry 一. 安装docker 1.确保yum packages 是最新的 2.添加yum repo 3.安装docker 4.启动docker 5.验证docker已经启动 6.安装--Docker ...

_Change_
2018/11/06
176
0

没有更多内容

加载失败,请刷新页面

加载更多

64.监控平台介绍 安装zabbix 忘记admin密码

19.1 Linux监控平台介绍 19.2 zabbix监控介绍 19.3/19.4/19.6 安装zabbix 19.5 忘记Admin密码如何做 19.1 Linux监控平台介绍: 常见开源监控软件 ~1.cacti、nagios、zabbix、smokeping、ope...

oschina130111
今天
13
0
当餐饮遇上大数据,嗯真香!

之前去开了一场会,主题是「餐饮领袖新零售峰会」。认真听完了餐饮前辈和新秀们的分享,觉得获益匪浅,把脑子里的核心纪要整理了一下,今天和大家做一个简单的分享,欢迎感兴趣的小伙伴一起交...

数澜科技
今天
7
0
DNS-over-HTTPS 的下一代是 DNS ON BLOCKCHAIN

本文作者:PETER LAI ,是 Diode 的区块链工程师。在进入软件开发领域之前,他主要是在做工商管理相关工作。Peter Lai 也是一位活跃的开源贡献者。目前,他正在与 Diode 团队一起开发基于区块...

红薯
今天
9
0
CC攻击带来的危害我们该如何防御?

随着网络的发展带给我们很多的便利,但是同时也带给我们一些网站安全问题,网络攻击就是常见的网站安全问题。其中作为站长最常见的就是CC攻击,CC攻击是网络攻击方式的一种,是一种比较常见的...

云漫网络Ruan
今天
12
0
实验分析性专业硕士提纲撰写要点

为什么您需要研究论文的提纲? 首先当您进行研究时,您需要聚集许多信息和想法,研究论文提纲可以较好地组织你的想法, 了解您研究资料的流畅度和程度。确保你写作时不会错过任何重要资料以此...

论文辅导员
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部