twisted web获取主机:端口元组异步响应中

2024-04-18 13:13:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我可以使用以下示例发出异步请求: http://twistedmatrix.com/documents/current/web/howto/client.html

我可以得到里面的异步响应接收的协议数据()但如何找出哪个响应映射到哪个请求?我想把我得到的回复映射回原来的主机:端口/请求。在

还有,像我现在这样使用global安全吗?在

class ClientResponseProtocol(Protocol):

  def __init__(self, whenFinished):
      self.whenFinished = whenFinished

  def dataReceived(self, bytes):
    global BUILD_REVISION

    d = json.loads(bytes)
    bv = d.get("build_revision")

    if bv in BUILD_REVISION:
      BUILD_REVISION[bv] += 1
    else:
      BUILD_REVISION[bv] = 1

  def makeConnection(self, transport):
    pass

  def connectionLost(self, reason):
    self.whenFinished.callback(None)

def handleResponse(r):
  #print("version=%s\ncode=%s\nphrase='%s'" % (r.version, r.code, r.phrase))
  #for k,v in r.headers.getAllRawHeaders():
  #  print(k, v)
  finished = twisted.internet.defer.Deferred()
  r.deliverBody(ClientResponseProtocol(finished))
  return finished

def handleError(reason):
  reason.printTraceback()
  reactor.stop()

def getPage(url):
  d = Agent(reactor).request('GET', url, Headers({'User-Agent': ['user']}), None)
  d.addCallbacks(handleResponse, handleError)
  return d


semaphore = twisted.internet.defer.DeferredSemaphore(BATCH_SIZE)
dl = list()

for server in servers:
  dl.append(semaphore.run(getPage, 'http://%s/server_info.json' % server))

dl = twisted.internet.defer.DeferredList(dl)
dl.addCallbacks(lambda x: reactor.stop(), handleError)

reactor.run()

Tags: inbuildselfdeftwistedrevisioninternetdefer
2条回答

您可以向Deferred回调传递额外的参数:

d.addCallback(f, extra, positional, args, keyword=args)

例如:

^{pr2}$

或者循环:

list_of_results = []
for server in list_of_servers:
    url = 'http://%s/server_info.json' % server
    d = getPage(url)
    d.addCallback(report_result, request_url=url)
    list_of_results.append(d)

all_requests = DeferredList(list_of_results)
...

另外,您可能还需要查看twisted.web.client.Agent,以取代对{}的使用。在

  • 首先,不要使用全局变量。这是邪恶的。在
  • 其次,Twisted为每个连接创建协议实例。因此,您将在Protocol.__init__()中定义的所有属性都将是“连接范围”。在
  • 第三,每个协议实例都应该与描述连接(例如tcp)的传输连接。传输对象包含您需要的数据,可以这样检索:
def makeConnection(self, transport):
    # for a TransportProxyProducer
    host = transport._producer.getPeer().host
    port = transport._producer.getPeer().port

以下是api文档的一些链接,可能会有所帮助:

相关问题 更多 >