python-qpid-proton 示例,向 azure 发送消息不起作用

Posted

技术标签:

【中文标题】python-qpid-proton 示例,向 azure 发送消息不起作用【英文标题】:python-qpid-proton examples, send message to azure not working 【发布时间】:2015-11-18 07:22:27 【问题描述】:

我正在尝试使用 python-qpid-proton 0.9.1 版向 Azure 服务总线队列发送消息。

examples/python/messenger/ 中的示例接受amqps://<user>:<password>@<server>/<queue name> 形式的地址,我可以使用它成功地将消息发送到 Azure 上的队列。这样做的问题是我无法控制正在发生的大部分事情,即我无法真正看到发送是否失败。最后,我想保留这些消息,以防互联网连接暂时中断。

示例代码examples/python/db_send.pyexamples/python/simple_send.py 似乎在这方面更有用,因为它们使用MessagingHandler 而不是Messenger 类。但是当我运行它们时,我得到了这个错误:

./simple_send.py -a amqps://send:mxirestofmypassword@testsoton.servicebus.windows.net/queue2
Traceback (most recent call last):
  File "./simple_send.py", line 62, in <module>
    Container(Send(opts.address, opts.messages)).run()
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 120, in run
    while self.process(): pass
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 143, in proce
    self._check_errors()
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3737, in dis
    ev.dispatch(self.handler)
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3662, in dis
    result = dispatch(handler, type.method, self)
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3551, in dis
    return m(*args)
  File "/usr/local/lib/python2.7/dist-packages/proton/handlers.py", line 416, in on_r
    self.on_start(event)
  File "./simple_send.py", line 36, in on_start
    event.container.create_sender(self.url)
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 671, in creat
    session = self._get_session(context)
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 634, in _get_
    return self._get_session(self.connect(url=context))
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 611, in conne
    if url: connector.address = Urls([url])
  File "/usr/local/lib/python2.7/dist-packages/proton/reactor.py", line 555, in __ini
    self.values = [Url(v) for v in values]
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3851, in __i
    if defaults: self.defaults()
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3894, in def
    self.port = self.port or self.Port(self.scheme)
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3868, in _ge
    return portstr and Url.Port(portstr)
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3812, in __n
    port = super(Url.Port, cls).__new__(cls, cls._port_int(value))
  File "/usr/local/lib/python2.7/dist-packages/proton/__init__.py", line 3833, in _po
    raise ValueError("Not a valid port number or service name: '%s'" % value)
ValueError: Not a valid port number or service name: 'mxitheresto'

在我看来,它无法正确解析地址。我粘贴了与以前相同的地址。我还把它粘贴到了python解释器中,像这样:

>>> import proton
>>> u = proton.Url("amqps://send:mxirestofmypassword@testsoton.servicebus.windows.net/queue2")
>>> # no error, and I can access all the parameters:
>>> u.port
5671
>>> u.username
send
>>> # ...

如果我使用没有用户名和密码的本地连接,它可以正常工作。如果我不使用任何用户名和密码但显然无法通过身份验证,则可以通过这一点。

有什么方法可以使用MessagingHandler 类并指定用户名和密码来向远程发送消息(比如在 Azure 上)?

【问题讨论】:

【参考方案1】:

我尝试运行 qpid 示例“simple_send.py”,但没有任何错误。示例程序可以请求 Azure 服务总线,但无法与 AMQPS 方案建立发送方连接。

根据 MSDF 官方文档https://msdn.microsoft.com/en-us/library/azure/jj841070.aspx,您可以使用 Messenger 类向 Azure Service Bus 发送消息。

简单完成的示例代码如下:

from proton import Messenger, Message

messenger = Messenger()
message = Message()
message.address = "amqps://<shared_access_policy_name>:<shared_access_policy_key>@pandaservibus.servicebus.windows.net/testqueue"

message.body = u"This is a text string"
messenger.put(message)
messenger.send()

您可以在 Azure 服务总线队列页面的“配置”选项卡中获取共享访问策略名称和密钥。

最好的问候。


示例代码(克服不可靠的互联网连接):

from proton import Messenger, Message
from time import sleep

message = Message()
message.address = "amqps://<shared_access_policy_name>:<shared_access_policy_key>@pandaservibus.servicebus.windows.net/testqueue"
message.body = u"This is a text string"
print('start')
retry = True
print("Send Msg")
while retry:
    try:
        messenger = Messenger()
        messenger.put(message)
        messenger.send()
        retry = False
        print "Sent"
    except:
        print "Retry"
    sleep(2)
print "End"

如果您想成功检查发送消息的信号,我建议使用服务总线 REST API。发送消息成功后可以得到响应状态码 201。关于Service Bus REST API,请参考https://msdn.microsoft.com/en-us/library/azure/hh780786.aspx和https://msdn.microsoft.com/library/dn170477.aspx。

【讨论】:

我知道 Messenger 界面,并说明了我遇到的问题,即我无法检查消息是否成功发送。系统将在互联网连接不可靠的设备上运行。有什么办法可以克服 Messenger 界面的这个限制? @VladV 我为互联网连接不可靠的场景添加了一个示例代码。

以上是关于python-qpid-proton 示例,向 azure 发送消息不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Python 正则表达式零宽正负向断言的用法及示例代码

OpenMP 与向量化的比较

向局域网共享文件夹 写文件(示例)

任何人都可以向我展示如何向 UIScrollView 添加文本的示例吗?

python-示例(基本知识巩固)

向指标添加示例