2008-09-30 12 views
6

Python'da yazdığım ve bir veritabanı sisteminden veri alıp bunu XML olarak kullanıcıya döndüren küçük bir web sunucusu uygulamasına sahibim. Bu bölüm iyi çalışıyor - Python web sunucusu uygulamasını komut satırından çalıştırabilirim ve istemcilerin de ona bağlanıp verileri geri almasını sağlayabilirim. Şu anda web sunucusunu çalıştırmak için sunucumuza yönetici kullanıcısı olarak giriş yapmalı ve web sunucusunu manuel olarak başlatmam gerekiyor. Web sunucusunun otomatik olarak sistem başlangıcında bir hizmet olarak başlatılmasını ve arka planda çalışmasını istiyorum.Bir Python web sunucusunu Windows'ta hizmet olarak çalıştırıyor

ActiveState 's sitesinden ve StackOverflow kodundan yararlanıyorsanız, bir hizmet oluşturmayla ilgili nasıl giderim konusunda oldukça iyi bir fikrim var ve sanırım bu biraz sıralıyım - Web sunucumu yükleyebilir ve başlatabilirim Windows servisi Bununla birlikte, servisi tekrar nasıl durduracağımı anlayamıyorum. Benim web sunucusu bir BaseHTTPServer oluşturulur:

server = BaseHTTPServer.HTTPServer(('', 8081), SIMSAPIServerHandler) 
server.serve_forever() 

serve_forever() çağrısı, doğal olarak, sonsuz döngüye web sunucusu sit yapar ve HTTP bağlantıları (veya ctrl-break bir tuşa basıldıktan için kullanışlı değildir beklemek servis). Yukarıdaki örnek koddan, ana() işlevinizin sonsuz bir döngüde oturması ve yalnızca bir "durdurma" koşulunun söz konusu olduğunda yalnızca bunun dışında kalması gerektiği fikrini alırım. Ana çağrılarım serve_forever(). Ben komut satırından "piton MyService dur" ne zaman denilen olsun görünüyor

def SvcStop(self): 
    self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
    exit(0) 

ama değil (Ben bir dosyaya çıktı üretir Oradaki bir hata ayıklama satır koyabilirsiniz): Bir SvcStop fonksiyonu var - aslında bütün hizmet çıkmak "piton MyService başlangıcında" yapılan çağrılar, bana bir hata veriyor:

Error starting service: An instance of the service is already running.

ve durdurmak için daha sonraki aramaları bana verir:

Error stopping service: The service cannot accept control messages at this time. (1061)

Sanırım biraz re ya gerek serve_forever (serve_until_stop_received veya neyse) için yerleşim veya SvcStop'u değiştirmenin bir yoluna ihtiyacım var, böylece tüm hizmeti durdurur.

İşte tam liste (ı kesilmiş ettik içerir/yorumlarınızı yer kazanmak için):

yerine doğrudan sınıf BaseHTTPServer.HTTPServer örneklilik, ben yazın:

class SIMSAPIServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): 
    def do_GET(self): 
     try: 
      reportTuple = self.path.partition("/") 
      if len(reportTuple) < 3: 
       return 
      if reportTuple[2] == "": 
       return 
      os.system("C:\\Programs\\SIMSAPI\\runCommandReporter.bat " + reportTuple[2]) 
      f = open("C:\\Programs\\SIMSAPI\\out.xml", "rb") 
      self.send_response(200) 
      self.send_header('Content-type', "application/xml") 
      self.end_headers() 
      self.wfile.write(f.read()) 
      f.close() 
      # The output from CommandReporter is simply dumped to out.xml, which we read, write to the user, then remove. 
      os.unlink("C:\\Programs\\SIMSAPI\\out.xml") 
      return 
     except IOError: 
      self.send_error(404,'File Not Found: %s' % self.path) 



class SIMSAPI(win32serviceutil.ServiceFramework): 
    _svc_name_ = "SIMSAPI" 
    _svc_display_name_ = "A simple web server" 
    _svc_description_ = "Serves XML data produced by SIMS CommandReporter" 

    def __init__(self, args): 
     win32serviceutil.ServiceFramework.__init__(self, args) 
     self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)   

    def SvcStop(self): 
      self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
      exit(0) 

    def SvcDoRun(self): 
     import servicemanager 
     servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, '')) 

     self.timeout = 3000 

     while 1: 
      server = BaseHTTPServer.HTTPServer(('', 8081), SIMSAPIServerHandler) 
      server.serve_forever() 

def ctrlHandler(ctrlType): 
    return True 

if __name__ == '__main__': 
    win32api.SetConsoleCtrlHandler(ctrlHandler, True) 
    win32serviceutil.HandleCommandLine(SIMSAPI) 

cevap

3

Bu benim yaptığım bir "dur" yöntemini yayınlayan bundan yeni torun: zaten sahip yöntem SvcStop sonra

class AppHTTPServer (SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): 
    def serve_forever(self): 
     self.stop_serving = False 
     while not self.stop_serving: 
      self.handle_request() 

    def stop (self): 
     self.stop_serving = True 

Ve ben serve_forever kırmak için bu yöntemi çağırın() Döngü:

def SvcStop(self): 
    self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
    self.httpd.stop() 

(self.httpd AppHTTPServer (örneği olan) web sunucusu uygulayan)

doğru arka parçacıklarının) setDaemon (kullanmak ve doğru tüm döngüler kesintiye uğrarsa servis, SvcStop sonra talimat

exit(0) 

()

+0

aynı bağlamda [burada] (http://stackoverflow.com/questions/228 söz yardımcı olabilir gerekli olmamalıdır 14933/make-sunucu ve konsol-cin-as-hizmet-içinde-pencere) –

İlgili konular