|
AsyncHTTPClient是 tornado.httpclinet 提供的一個異步http客戶端。使用也比較簡單。與服務進程一樣,AsyncHTTPClient也可以callback和yield兩種使用方式。前者不會返回結果,后者則會返回response。 示例: 1 class AsyncHandler(tornado.web.RequestHandler): 2 @tornado.web.asynchronous 3 def get(self, *args, **kwargs): 4 5 url = 'https://api.github.com/' 6 http_client = tornado.httpclient.AsyncHTTPClient() 7 http_client.fetch(url, self.on_response) 8 self.finish('It works') 9 10 @tornado.gen.coroutine 11 def on_response(self, response): 12 print response.code 同樣,為了獲取response的結果,只需要yield函數。使用yield的時候,handler是需要 tornado.gen.coroutine。 1 class AsyncResponseHandler(tornado.web.RequestHandler): 2 @tornado.web.asynchronous 3 @tornado.gen.coroutine 4 def get(self, *args, **kwargs): 5 6 url = 'https://api.github.com/' 7 http_client = tornado.httpclient.AsyncHTTPClient() 8 response = yield tornado.gen.Task(http_client.fetch, url) 9 print response.code 10 print response.body 如果業(yè)務處理并不是在handlers寫的,而是在別的地方,當無法直接使用tornado.gen.coroutine的時候,可以構造請求,使用callback的方式。 1 body = urllib.urlencode(params) 2 req = tornado.httpclient.HTTPRequest( 3 url=url, 4 method='POST', 5 body=body, 6 validate_cert=False) 7 8 http_client.fetch(req, self.handler_response) 9 10 def handler_response(self, response): 11 12 print response.code AsyncHTTPClient中的fetch方法,第一個參數其實是一個HTTPRequest實例對象,因此對于一些和http請求有關的參數,例如method和body,可以使用HTTPRequest先構造一個請求,再扔給fetch方法 1 def getURL(): 2 2 # 接口地址 3 3 url = "http://ip:port/Get2" 4 4 5 5 6 6 payload = {"key":"914683196200","timestamp":"2019-07-11 11:27:21","partner_id":"1","sign":"C77CAAA496FE0D385410A"} 7 7 # verify = False 忽略SSH 驗證 8 8 9 9 try: 10 response = requests.post(url, json=payload, timeout=5) # 超時的時候回報錯并重試 11 print(r.json()) 12 except ReadTimeout: 13 # 超時異常 14 print('Timeout') 15 return 1 16 except ConnectionError: 17 # 連接異常 18 print('Connection error') 19 return 2 20 except RequestException as e: 21 # 請求異常 22 print('Error') 23 print('str(Exception):\t', str(Exception)) 24 print('str(e):\t\t', str(e)) 25 print('repr(e):\t', repr(e)) 注意:使用異步,必須tornado.ioloop.IOLoop.instance().start 啟動 IOLoop 的實例,啟動事件循環(huán)機制,配合非阻塞的 HTTP Server 工作
 callback_async 1 @coroutine 2 def post ( self, url, body, domain=None ) : 3 try : 4 request = AsyncHTTPClient() 5 response = yield request.fetch(url, method="POST", body=body) 6 logger.info("url: {0} code: {1}".format(url, response.code)) 7 self.retry() 8 raise Return(True) 9 except Return : 10 pass 11 except Exception as e : 12 print('str(Exception):\t', str(Exception)) 13 print('str(e):\t\t', str(e)) 14 print('repr(e):\t', repr(e)) 15 print('e.message:\t', e.message) 16 logger.exception("url: {0}".format(url)) 17 self.push(uri, body, domain) 18 self.reload_domain() 19 raise Return(False) 20 21 22 @coroutine 23 def post_callback ( self, url, body, domain=None, call_back=None, error_back=None, retry_times=3 ) : 24 try : 25 request = AsyncHTTPClient() 26 27 response = yield request.fetch(url, method="POST", body=body) 28 logger.info("url: {0} code: {1}".format(url, response.code)) 29 if call_back : 30 call_back(response) 31 except Exception as e : 32 print('str(Exception):\t', str(Exception)) 33 print('str(e):\t\t', str(e)) 34 print('repr(e):\t', repr(e)) 35 print('e.message:\t', e.message) 36 if retry_times > 0 : 37 logger.info("url: {0} retry: {1}".format(url, retry_times)) 38 retry_times -= 1 39 IOLoop.instance().call_later(1, self.post_callback, uri, body, domain, call_back, error_back, 40 retry_times) 41 else : 42 logger.exception("url: {0}".format(url)) 43 if error_back : 44
|