【问题标题】:How to handle callbacks in Python 3?如何在 Python 3 中处理回调?
【发布时间】:2019-10-16 04:26:15
【问题描述】:

我有一个自定义的 HTTP 方法/动词(比如说LISTEN),它允许我监听存储在远程服务器上的资源的更新。为此可用的 API 有一个阻塞调用,它将让我的客户端代码监听更新,直到我中断该调用的执行。举个例子,如果我要执行如下卷曲:

curl -X LISTEN http://<IP-Address>:<Port>/resource

执行此操作会创建一个阻塞调用,每当此资源的新值被推送到服务器时(类似于 pub-sub 模型),为我提供有关资源的更新,对此的响应将类似于以下内容:

{"data":"value update 1","id":"id resource"}
{"data":"value update 2","id":"id resource"}
(...)

如果我要在 Python 中编写代码来处理这个问题,我如何使用这个自定义动词调用我的 url 并处理阻塞调用/回调,同时确保这不会阻塞我其余代码的执行?

【问题讨论】:

标签: python python-3.x callback python-requests


【解决方案1】:

如果你使用 Python requests lib with a custom HTTP verbneed to read stream content,你可以这样做:

import json
import requests  # sudo pip3 install requests


url = "http://........."
r = requests.request('LISTEN', url, stream=True)
for line in r.iter_lines():
    # filter out keep-alive new lines
    if line:
        decoded_line = line.decode('utf-8')
        print(json.loads(decoded_line))

注意:默认情况下,所有requests 调用都是阻塞的,因此您需要在单独的线程/进程中运行此代码以避免这种情况。

...同时确保这不会阻止我其余代码的执行

由于您没有提供有关您的申请的详细信息,因此我将尝试列出一些关于问题的一般想法。

您的任务可以通过多种方式来解决。解决方案取决于您的应用架构。

如果这是一个网络服务器,您可以查看tornado(参见流式回调)或aiohttp 流式示例。

另一方面,您可以在单独的进程中运行上述代码,并使用 RabbitMQ(或其他 ipc 机制)与其他应用程序/服务进行通信。

【讨论】:

  • 我尝试运行你的 sn-p 但我遇到了同样的问题,即它处于阻塞状态。为了扩展我的问题,我正在尝试调用名为 OpenDHT 的开源 DHT 实现的 LISTEN 函数。
  • 在此,我使用其 REST 端点与此应用程序交互并获取与存储在此 DHT 网络上的资源(键)关联的值。我尝试查看Requests 库,但未能成功调用自定义动词LISTEN,同时能够执行一些其他逻辑,例如 - 从文件中读取数据并对其运行一些计算,然后将其放置在 DHT 网络上并触发对插入 DHT 的资源/密钥的LISTEN 调用。阅读过程和LISTEN应该同时进行
  • 是的,对不起,我没有提到任何requests 调用都是阻塞的,所以如果你想以非阻塞方式使用这个sn-p,你应该把它放在一个单独的进程或线程(我会选择一个进程,请参阅答案的最后一句话)。
  • 感谢您指出这个概念。我确实考虑过并最终在 Python 中查看了asyncio,但我仍然面临同样的问题。此端点形成一个连接,并一次发送一个值(作为 JSON),但是当我进行 LISTEN 调用时,它始终保持在该状态而没有进一步进展,因此我无法访问任何值(如果完全被退回)。老实说,我不确定如何解决这个问题。
猜你喜欢
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 2017-11-06
  • 2014-01-27
  • 2012-05-14
  • 1970-01-01
相关资源
最近更新 更多