我可以使用以下示例制作异步请求: http://twistedmatrix.com/documents/current/web/howto/client.html
我可以在Protocol.dataReceived()中获取异步响应,但是如何找出哪个响应映射到哪个请求?我想将我回复的响应映射到原始主机:port / request。
此外,像我在这里一样使用全球安全吗?
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()
答案 0 :(得分:1)
您可以将额外参数传递给Deferred
回调:
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
的使用。
答案 1 :(得分:0)
Protocol.__init__()
中定义的所有属性将是"连接范围"。def makeConnection(self, transport): # for a TransportProxyProducer host = transport._producer.getPeer().host port = transport._producer.getPeer().port
以下是可能有用的api文档的一些链接: