2011-07-06 7 views
6

Escribo un servidor web simple en python. He aquí una versión simplificada de mi código:SimpleHTTPRequestHandler cierra la conexión antes de regresar del método do_POST

class StreamerHandler(SimpleHTTPRequestHandler): 
    def do_POST(self): 
     try: 
      length = int(self.headers.getheader('content-length')) 
      data = self.rfile.read(length) 
      self.send_response(200, "OK") 
      #process_data(data, self.client_address) 
     except Exception as inst: 
      logging.error(type(self).__name__ + "/" + type(inst).__name__ + " (" + inst.__str__() + ")") 

class Streamer(TCPServer): 
    def __init__(self, overlay): 
     self.allow_reuse_address = True 
     TCPServer.__init__(self, ("", port), StreamerHandler) 

Lo que me gustaría hacer es enviar la respuesta cerrar la conexión TCP y luego ejecutar el método process_data que puede tardar mucho tiempo en completarse.

¿Hay alguna manera de lograr esto? La única solución que puedo pensar es utilizar un hilo dedicado para manejar el procesamiento.

+0

en lugar de tener un segundo hilo ** ** usted podría intentar tener un segundo ** proce ss **, esto es un poco más pesado pero te libera de tener que manejar el bloqueo. Ver [docs] (http://docs.python.org/library/multiprocessing.html). – mac

Respuesta

3

lo probé, que realmente necesita ambos comandos (en orden) para cerrarla: self.finish() self.connection.close()

2

Por lo tanto, SimpleHTTPRequestHandler hereda de BaseHTTPServer.BaseHTTPRequestHandler, que a su vez hereda de SocketServer.StreamRequestHandler.

En SocketServer.StreamRequestHandler, los archivos seudo rfile y wfile se crean en el método setup() del objeto socket (conocido como self.connection):

def setup(self): 
    self.connection = self.request 
    if self.timeout is not None: 
     self.connection.settimeout(self.timeout) 
    if self.disable_nagle_algorithm: 
     self.connection.setsockopt(socket.IPPROTO_TCP, 
            socket.TCP_NODELAY, True) 
    self.rfile = self.connection.makefile('rb', self.rbufsize) 
    self.wfile = self.connection.makefile('wb', self.wbufsize) 

La toma self.connection todavía está disponible para usted, por lo que se podría llamar self.connection.close() para cerrarlo Sin embargo, el pseudo-archivo wfile podría haber buffer de datos en su interior, que se podrían perder, por lo que podría/lugar debe llamar self.finish(), también se define en SocketServer.StreamRequestHandler:

def finish(self): 
    if not self.wfile.closed: 
     self.wfile.flush() 
    self.wfile.close() 
    self.rfile.close() 

Por lo tanto, creo que el siguiente debe funcionar (no probado) :

class StreamerHandler(SimpleHTTPRequestHandler): 
    def do_POST(self): 
     try: 
      length = int(self.headers.getheader('content-length')) 
      data = self.rfile.read(length) 
      self.send_response(200, "OK") 
      self.finish() 
      process_data(data, self.client_address) 
     except Exception as exc: 
      logging.error(
       "{0}/{1}({2})".format(
        type(self).__name__, type(exc).__name__, str(exc))) 
Cuestiones relacionadas