Форум сайта python.su
0
Добрый день,
возникла необходимость поставить таймаут на чтение данных через HTTPConnection, посоветуйте как
Проблема в чем - не уверен, что это хороший метод, может есть какое-то другое решение?
Написал для себя скрипт скачки большого кол-ва страничек, бывает что какой-то из потоков подвисает намертво из-за потери связи с сервером, и никакие таймауты сокетов не работают…
После поиска в инете, заранее несколько замечаний:
1. Писать свой собственный модуль на основе сокетов я не осилю
2. Требуется прервать именно работающий read() - связь установлена, данные идут, питон не получает ни ошибки, ни конца потока, и тут мы хотим все это дело прервать сиюмоментно, не дожидаясь ни единого байта (т.е. даже read(блоками) не подходит)
3. Использую HTTPConnection для Keep-Alive (в примере заголовки убраны для меньшего объема)
Для тестов на веб-сервере сделал искуственно замедленный скрипт (страничка выдается 20 сек) -
<?php
for ($a=1;$a<=20;$a++) {
echo($a."<br>");
sleep(1);
flush();
}
?>
server = "localhost" url = "http://localhost/delay/gen20.php" def timeout(sock): logger.info("Timeout, trying to reconnect") sock.close() def do_read(): conn = http.client.HTTPConnection(server,timeout=5) logger.debug("HTTP conn created") for errcount in range(5): conn.connect() logger.debug(url + " - start fetch. Try %d of 5" % (errcount+1)) try: conn.request("GET",url) resp = conn.getresponse() t = Timer(2,timeout,[conn.sock]) t.start() data = resp.read() print(data) t.cancel() break except socket.timeout: resp.close() del resp conn.close() continue
Отредактировано Andys (Май 16, 2014 11:43:06)
Офлайн
34
Посмотрите в сторону requests.
При запросе там можно указать параметр timeout
<?php
$timeout = intval($_GET['timeout']);
echo("timeout: ".$timeout."<br/>\n");
for ($a=1;$a<=$timeout;$a++) {
echo($a."<br>\n");
sleep(1);
flush();
}
?>
import requests url = 'http://example.com/test.php?timeout=5' try: r = requests.get(url, timeout=10) print 'Data recieved' except requests.exceptions.Timeout as e: print 'Got exception: {}'.format(e) try: r = requests.get(url, timeout=2) print 'Data recieved' except requests.exceptions.Timeout as e: print 'Got exception: {}'.format(e)
Data recieved
Got exception: HTTPConnectionPool(host='example.com', port=80): Read timed out. (read timeout=2)
Отредактировано GreyZmeem (Май 16, 2014 12:24:50)
Офлайн
0
Спасибо :)
Попробую с ним поработать, имо это будет проще чем отлавливать баги в моем скачивальщике.
Офлайн