You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在asyncio上运行Twisted客户端?代码卡顿问题求助

问题描述

我从Twisted官方文档借鉴了一段客户端代码,正在开发需兼容Twisted的asyncio项目,尝试用asyncio运行该代码,但程序始终卡在res = await d.asFuture(asyncio.get_event_loop())这一行。代码如下:

import asyncio

from twisted.internet import asyncioreactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers


asyncioreactor.install()


async def request():
    agent = Agent(asyncioreactor.AsyncioSelectorReactor)

    d = agent.request(
        b'GET',
        b'http://httpbin.com/anything',
        Headers({'User-Agent': ['Twisted Web Client Example']}),
        None)

    def cbResponse(ignored):
        print('Response received')

    d.addCallback(cbResponse)

    def cbShutdown(ignored):
        asyncioreactor.AsyncioSelectorReactor.stop()

    d.addBoth(cbShutdown)
    print("This is where it always get stuck")
    res = await d.asFuture(asyncio.get_event_loop())
    print("SUCCESSS!!!!")


if __name__ == "__main__":
    asyncio.run(request())

执行python request.py后无后续输出,请问用asyncio运行Twisted客户端是否可行?该如何解决卡顿问题?

解决方案

完全可行,你的代码存在两个关键问题:

  • 错误使用Reactor类而非实例:你直接传入asyncioreactor.AsyncioSelectorReactor类给Agent,而不是已经安装好的reactor实例。Twisted的Agent需要绑定到运行中的reactor实例,而非类本身。
  • 错误调用reactor的stop方法:你调用的是asyncioreactor.AsyncioSelectorReactor.stop()类方法,而非实例的stop方法,这无法正确停止reactor。

修正后的代码如下:

import asyncio

from twisted.internet import asyncioreactor, reactor
from twisted.web.client import Agent
from twisted.web.http_headers import Headers


asyncioreactor.install()


async def request():
    # 使用已安装好的reactor实例,而非类
    agent = Agent(reactor)

    d = agent.request(
        b'GET',
        b'http://httpbin.com/anything',
        Headers({'User-Agent': ['Twisted Web Client Example']}),
        None)

    def cbResponse(response):
        print('Response received')
        return response

    d.addCallback(cbResponse)

    def cbShutdown(_):
        # 调用实例的stop方法
        reactor.stop()

    d.addBoth(cbShutdown)
    print("Waiting for response...")
    res = await d.asFuture(asyncio.get_event_loop())
    print("SUCCESSS!!!!")
    return res


if __name__ == "__main__":
    # 启动reactor并运行异步任务
    asyncio.run(request())

额外注意点:

  • 安装asyncioreactor后,直接使用twisted.internet.reactor即可获取当前运行的reactor实例,无需手动创建。
  • asFuture方法需要传入正确的asyncio事件循环,这里asyncio.get_event_loop()在asyncio.run上下文里是正确的。
  • 回调函数里最好返回response,这样await后能拿到响应对象做后续处理。

内容的提问来源于stack exchange,提问作者Ruben Quinones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 03:35:28