Форум сайта python.su
Всем привет!
Есть необходимость контролировать и обмениваться данными с прокси сервером из приложения.
То есть, есть GUI с кнопками start/stop proxy. Так вот надо программно запускать прокси (сам класс прокси уже реализовал) и оставливать. При этом в самом классе прокси идет обработка данных, которые через него пропускаются и эти данные надо передать основному приложению. Загвоздка в том, что если в хендлере on_click запускать прокси (вызывать метод соответствующего объекта), то фактически приложение блокируется и ждет когда этот процесс кто-нить прибьёт.
Подскажите как правильно реализовывать подобное взаимодействие. Я так понимаю, надо в отдельный поток запускать сервер?
Офлайн
Первую часть почти не понял.
Понял начиная с места “Загвоздка в том, что если в хендлере on_click”: да. нужно вынести в отдельный поток. Например с помощью нитей (Threading).
Вот например почитать можно для понимания:
http://www.intuit.ru/department/pl/python/11/
Отредактировано (Авг. 23, 2008 17:53:35)
Офлайн
shiza, спасибо. потоки то, что надо. Но это только половина проблемы.
Ещё раз попробую объяснить суть задачи :)
Есть GUI приложение, в котором необходимо запускать, обмениваться данными и останавливать прокси сервер.
То есть есть кнопки “Start Proxy” и “Stop Proxy”.
В простейшем случае (тут пока без потоков) в обработчике клика по кнопке “Start Proxy” будет что-то типа:
HOST_NAME = '127.0.0.1'
PORT_NUMBER = 8080
server_class = BaseHTTPServer.HTTPServer
httpd = server_class((HOST_NAME, PORT_NUMBER), ProxyHandler)
print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
httpd.serve_forever()
Офлайн
pentoПопробуй такой вариант:
Но вот пока что не понятно, а как собственно останавливать этот сервер, то есть что писать в обработчике “Stop Proxy”
.....
#делаем таймаут на ожидание подключения (например 5), чтоб httpd.handle_request()
#не зависал намертво при отсуствеии подключений
httpd.socket.settimeout(5)
....
while 1:
if stop_command: #флаг, который надо поставить в True, когда захочется застопить сервер.
break
httpd.handle_request()
Отредактировано (Авг. 24, 2008 00:50:28)
Офлайн
По поводу общей архитектуры.
Не очень понятно про ту часть программы, которая обменивается данными с сервером.
Она привязана к GUI?
Просто тут есть 3 варианта.
Пускать ее в потоке с GUI;
пускать в потоке сервера (как кусок в цикле сервера);
пускать в отдельном своем потоке.
Офлайн
О, спасибо. Про цикл я что-то сразу не догадался.
shizaПрокси сервер временно влючается из основной программы. Затем через этот прокси происходит обмен HTTP трафиком, при этом этот трафик анализируется. Так вот результаты анализа потом и надо вернуть обратно в основную программу.
Она привязана к GUI?
Офлайн
Понятно.
Вообще если в GUI делать какие-нибудь длительные вычисления, то он на это время зависает и юзер начинает испытывать дискомфорт =).
Поэтому считается кошерным выносить эти самые вычисления в отдельный поток и в гуе прогресс-бар например показывать.
Если у тебя анализ трафика занимает много времени и потенциальный юзер привередлив - имеет смысл тоже так сделать =)
Офлайн
shiza, да нет. Там всего ничего..пара HTTP заголовков выкусываться будет. :) А прогресс бар не нужен будет. Юзер сам будет прописывать мой прокси у себя в браузере и фактически сам контролировать процесс.
Ещё раз спасибо за советы!
Офлайн
Кстати, таки сделал. Взаимодействие через события модуля threading =) Ещё раз спасибо за советы!
Отладочный код:
def kill_server(run_event):
print "Let's kill server!"
run_event.clear()
httpd = XcobraProxyServer()
run_event = threading.Event()
run_event.set()
p1 = threading.Thread(target=httpd.run, name="t1", args=[run_event])
p1.start()
t = threading.Timer(10.0, kill_server, [run_event])
t.start()
def run(self, run_event):
"""Runs server"""
self.socket.settimeout(5)
if self.verbose:
print "Starting Proxy Server on %s:%s" % self.server_address
while True:
if not run_event.isSet():
break
self.handle_request()
if self.verbose:
print "Stoping Proxy Server on %s:%s" % self.server_address
Отредактировано (Авг. 30, 2008 17:05:11)
Офлайн
=)
Офлайн