Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python twisted web get主机:异步响应中的端口元组_Python_Twisted - Fatal编程技术网

Python twisted web get主机:异步响应中的端口元组

Python twisted web get主机:异步响应中的端口元组,python,twisted,Python,Twisted,我能够使用以下示例发出异步请求: 我可以在Protocol.dataReceived()中获得异步响应,但如何找出哪个响应映射到哪个请求?我想将我得到的响应映射回原始主机:端口/请求 还有,像我在这里这样使用global安全吗 class ClientResponseProtocol(Protocol): def __init__(self, whenFinished): self.whenFinished = whenFinished def dataReceived

我能够使用以下示例发出异步请求:

我可以在Protocol.dataReceived()中获得异步响应,但如何找出哪个响应映射到哪个请求?我想将我得到的响应映射回原始主机:端口/请求

还有,像我在这里这样使用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()
  • 首先,不要使用globals。这是邪恶的
  • 其次,Twisted为每个连接创建协议实例。因此,您将在
    协议中定义的所有属性都将是“连接范围”
  • 第三,每个协议实例都应该与描述连接的传输(例如tcp)连接。传输对象包含您需要的数据,可以按如下方式检索:
以下是一些api文档的链接,可能会有所帮助:


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

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

def report_result(result, request_url):
    ...

url = 'http://%s/server_info.json' % server
d = getPage(url)
d.addCallback(report_result, request_url=url)
或在循环中:

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
,以替换您使用的
getPage

,因为它不起作用。我为上下文添加了更多代码。我拥有的唯一传输(TransportProxyProducer)变量是makeConnection()内部的变量,它似乎不包含getPeer()。exceptions.AttributeError:“TransportProxyProducer”对象没有属性“producer”。这是一个协议类,应该在那里吗?对不起,我弄错了,我又更新了一次我的答案,
transport.\u producer
应该是而不是
transport.producer
我将响应转到ClientResponseProtocol。我需要该类中的url,以便将HTTP响应映射到原始请求。这些回调参数在哪里可用?它们只是更多的参数。您可以将它们传递给任何您想传递给的对象,包括传递给
ClientResponseProtocol.\uu_uinit\uu
,如果您愿意的话。
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)
...