2013-08-15 3 views
1

POST 패킷을 처리하는 Python 서버를 설정하려고합니다. 패킷이 도착하면 do_POST는 새 스레드를 & 데이터, 일부로 채우고 스레드는 일부 물건을 수행하고 출력을받은 자체 개체를 넣습니다.다중 스레드 응답 핸들러가있는 Python http 서버

from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer 
.... 
class httpHandler(BaseHTTPRequestHandler): 
    def do_POST(self): 
     length = int(self.headers['content-length']) 
     data = self.rfile.read(length) 
     Resolver(self,data).start() 
     return 

그런 다음 내 해결 클래스에서 내가 할 : 이 내가 지금까지 무엇을 가지고 물론

class Resolver(threading.Thread): 
    def __init__(self,http,number): 
     threading.Thread.__init__(self) 
     self.http = http 
     self.number = number + "!" 

    def run(self): 
     self.http.send_response(200) 
     self.http.send_header('Content-type','text/html') 
     self.http.send_header('Content-length', len(self.number)) 
     self.http.end_headers() 
     # Send the html message 
     self.http.wfile.write(self.number) 
     return 

스레딩 수입이 나는 ', 예를 들어이 아니라 전체 시트입니다 여전히 내 프로그램을 테스트하는 단계에 있습니다. 약한 플랫폼 (현재는 라즈베리 파이)에서 실행되며 좋은 성능 솔루션을 찾고 있습니다. 제안 사항이 있으십니까?

+1

연결 당 스레드 대신 요청 당 스레드가 필요합니다 (수동으로 구현하는 대신 내장 된 TheadingMixIn을 사용할 수 있음)? – abarnert

+0

글쎄요, 큰 범위는 다음과 같습니다. 연결을 실행하는 내 메인 클래스는 db 연결 (pycopg2 모듈 사용)을 유지하고 새로운 포스트 패킷이 도착할 때마다 커서를받습니다. 그런 다음 요청이 분석되고 출력이 응답 패킷으로 반환됩니다. ThreadingMixIn이 매우 느린 곳을 읽었습니다. 그래서 나는 그것을 의지하기를 두려워했다. 틀 렸으면 고쳐줘.각각의 연결은 보통 매우 짧습니다 : 요청, 결과 얻기 및 완료 – buddy123

+0

파이썬에서 다중 쓰레드를 사용하는 것은 일반적으로 일반적으로 좋지 않습니다. 그러나 스레드의 목적이 데이터베이스 연결과 대화하는 것이면 적어도 각 요청 처리기가 데이터베이스와 통신하는 동안 다른 스레드를 실행할 수 있어야합니다. 직접 작성하려고 시도해도 더 빨리 처리 할 수는 없습니다./ – Iguananaut

답변

1

올바른 방법이 아닙니다. 이제 요청을 보내는 각 스레드는 "동시에"HTTP 서버를 통해 응답을 작성하게됩니다. 잠금 기능을 추가 할 수는 있지만 기본적으로 목적을 상실 할 수 있습니다.

파이썬에는 이미이 작업을 수행하는 간단한 기본 제공 방법이 있습니다. BaseHTTPServer.HTTPServerSocketServer.TCPServer의 하위 클래스이므로 SocketServer.ThreadingMixIn 만 사용할 수 있습니다.

http://docs.python.org/2/library/socketserver.html#asynchronous-mixins

이미 SO도에이 작업을 수행하는 방법의 예를 존재가 확신 : 파이썬 문서는 여기에 예를 제공합니다.

2

do_POST에서 반환 할 때까지 요청을 완료 할 것으로 예상됩니다. , 당신이 더 깊이 보면

mname = 'do_' + self.command 
# ... 
method = getattr(self, mname) 
mname() 
self.wfile.flush() #actually send the response if not already done. 

, 당신이 나타납니다 : 당신의 방법은 호출하는 방법이 문서에서 모든 것을 명확하지 않다, 그러나 당신이 handle_one_request에 소스를 보면 즉시 명백 예상대로 코드는 요청을 처리하는 즉시 연결을 닫거나 다시 사용할 수있을 것으로 기대합니다.

따라서 BaseHTTPRequestHandler을이 방법으로 사용할 수 없습니다.

물론 직접 처리기 구현을 작성할 수 있습니다. 대체로 BaseHTTPServer의 내용은 강력하고 효율적이며 견고하고 유연한 프레임 워크 이상의 샘플 코드로 제공됩니다 (이것이 바로 문서가 소스에 직접 연결되는 이유입니다).

요청에 따라 스레드를 만들지 않고 연결 당 스레드를 만들면됩니다. ThreadingMixIn 클래스는 이것을 쉽게 만듭니다.

더 나은 솔루션은 Twisted 또는 Tornado와 같은 더 나은 프레임 워크를 사용하거나 스레딩을 수행하고 WSGI를 통해 코드를 호출하는 웹 서버를 사용하는 것입니다.

+0

토네이도 BTW는 +1하기가 매우 쉽기 때문에 +1을 추가하겠습니다. – Iguananaut

+0

내 파이썬 코드 쓰루 WSGI를 실행하는 서버에는 어떤 종류가 있습니까? 나는 그것의 많은 것을 모른다. PHP/Apache 서버를 의미합니까? 파이썬의 BaseHTTPServer 클래스 대신 Tornado를 사용해야합니까? 그리고, 또한 .. 토네이도는 ThreadingMixIn보다 나은 프레임 워크입니까? – buddy123

+0

"PHP/Apache"를 사용할 필요가 없습니다. PHP 코드가 없으므로 PHP 모듈이없는 아파치도 제대로 작동합니다. 그래서 nginx, 또는 다른 것입니다. 구성하기 만하면 (또는 최악의 경우 WSGI 모듈을 추가해야하는) 장치에 서버가 내장되어있을 수도 있습니다. – abarnert