2016-07-05 64 views
5

Sono nuovo in Python e ho scritto un semplice httpserver in python. Sto cercando di spegnere il server dalla richiesta al server. Come posso ottenere questa funzionalità di chiamare una funzione del server dal gestore?Come fermare un server simplehttps in python da httprequest handler?

class MyHandler(SimpleHTTPRequestHandler): 
    def do_GET(self): 
     if self.path == '/shutdown': 
      pass # I want to call MainServer.shutdown from here 


class MainServer() 
    def __init__(self, port = 8123): 
     self._server = HTTPServer(('0.0.0.0', port), MyHandler) 
     self._thread = threading.Thread(target = self._server.serve_forever) 
     self._thread.deamon = True 


    def start(self): 
     self._thread.start() 

    def shut_down(self): 
     self._thread.close() 

risposta

2

In breve, non utilizzare server.serve_forver(..). Il gestore delle richieste ha un attributo self.server che è possibile utilizzare per comunicare con l'istanza del server principale per impostare una sorta di contrassegno che indica al server quando fermarsi.

import threading 
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer 

class MyHandler(BaseHTTPRequestHandler): 
    def do_GET(self): 
     if self.path == '/shutdown': 
      self.server.running = False 


class MainServer: 
    def __init__(self, port = 8123): 
     self._server = HTTPServer(('0.0.0.0', port), MyHandler) 
     self._thread = threading.Thread(target=self.run) 
     self._thread.deamon = True 

    def run(self): 
     self._server.running = True 
     while self._server.running: 
      self._server.handle_request() 

    def start(self): 
     self._thread.start() 

    def shut_down(self): 
     self._thread.close() 

m = MainServer() 
m.start() 
1

Il server è normalmente accessibile dal gestore tramite l'attributo server. Un HTTPServer avviato con server_forerver può essere chiuso con il suo metodo ... shutdown(). Sfortunatamente, anche se non è documentato, non puoi chiamare shutdown dal thread che esegue il loop del server perché causa un deadlock. Così si potrebbe scrivere questo nel metodo do_GET gestore:

def do_GET(self): 
    # send something to requester... 
    if self.path == '/shutdown': 
     t = threading.Thread(target = self.server.shutdown) 
     t.daemon = True 
     t.start() 

Questo modo pulito lasciare che il filo per terminare, e si dovrebbe anche usarlo come metodo di server di shut_down, perché le discussioni Python non possono essere chiusi bruscamente:

def shut_down(self): 
    self._server.shutdown()