2014-01-20 4 views
3

Я читаю XML-события с библиотекой запросов, как указано в приведенном ниже коде. Как я могу получить ошибку с потерей соединения после запуска запроса? Сервер эмулирует HTTP-запрос/длинный опрос ->http://en.wikipedia.org/wiki/Push_technology#Long_polling и не будет завершен по умолчанию. Если после 10 минут не появилось нового сообщения, цикл while должен быть завершен.Python, тайм-аут улова во время запроса потока

import requests 
from time import time 


if __name__ == '__main__': 
    #: Set a default content-length 
    content_length = 512 
    try: 
     requests_stream = requests.get('http://agent.mtconnect.org:80/sample?interval=0', stream=True, timeout=2) 
     while True: 
      start_time = time() 
      #: Read three lines to determine the content-length   
      for line in requests_stream.iter_lines(3, decode_unicode=None): 
       if line.startswith('Content-length'): 
        content_length = int(''.join(x for x in line if x.isdigit())) 
        #: pause the generator 
        break 

      #: Continue the generator and read the exact amount of the body.   
      for xml in requests_stream.iter_content(content_length): 
       print "Received XML document with content length of %s in %s seconds" % (len(xml), time() - start_time) 
       break 

    except requests.exceptions.RequestException as e: 
     print('error: ', e) 

Сервер толчок может быть протестирована с загнутым через командную строку:

curl http://agent.mtconnect.org:80/sample\?interval\=0 

ответ

0

Это может быть не лучший метод, но вы можете использовать многопроцессорность для запуска запросов в отдельном процессе. Что-то, как это должно работать:

import multiprocessing 
import requests 
import time 

class RequestClient(multiprocessing.Process): 
    def run(self): 
     # Write all your code to process the requests here 
     content_length = 512 
     try: 
      requests_stream = requests.get('http://agent.mtconnect.org:80/sample?interval=0', stream=True, timeout=2) 

      start_time = time.time() 
      for line in requests_stream.iter_lines(3, decode_unicode=None): 
       if line.startswith('Content-length'): 
        content_length = int(''.join(x for x in line if x.isdigit())) 
        break 

      for xml in requests_stream.iter_content(content_length): 
       print "Received XML document with content length of %s in %s seconds" % (len(xml), time.time() - start_time) 
       break 
     except requests.exceptions.RequestException as e: 
      print('error: ', e) 


While True: 
    childProcess = RequestClient() 
    childProcess.start() 

    # Wait for 10mins 
    start_time = time.time() 
    while time.time() - start_time <= 600: 
     # Check if the process is still active 
     if not childProcess.is_alive(): 
      # Request completed 
      break 
     time.sleep(5) # Give the system some breathing time 

    # Check if the process is still active after 10mins. 
    if childProcess.is_alive(): 
     # Shutdown the process 
     childProcess.terminate() 
     raise RuntimeError("Connection Timed-out") 

Не идеальный код для вашей проблемы, но вы получите идею.

+0

Хм, похоже, что он работает. Тем не менее, я получаю только каждые 5 секунд XML-сообщение. Мне нужно, чтобы они были как можно быстрее;) – wiesson

+0

5-секундный сон фактически не зависает над дочерним процессом. Он просто спит в основной теме. XML-сообщение должно обрабатываться сразу же после его возврата в дочерний процесс. Скорее всего, сервер или модуль 'request' добавляет задержку в 5 секунд. –

+0

Если это сработало, вы, вероятно, можете пойти и принять ответ :) –