2009-11-16 2 views
4

J'ai une application en python avec une boucle principale personnalisée (je ne crois pas que les détails soient importants). Je voudrais intégrer un simple serveur web non bloquant dans l'application qui peut introspecter les objets de l'application et éventuellement fournir une interface pour les manipuler. Quelle est la meilleure façon de faire cela? Je voudrais éviter tout ce qui utilise le filetage. La solution idéale serait un serveur doté d'une fonction «step» qui peut être appelée depuis ma boucle principale, faire son truc, puis retourner le contrôle du programme jusqu'au prochain tour. Plus le niveau de la solution est élevé, mieux c'est (quoique quelque chose d'aussi monolithique que Django puisse être exagéré).Intégrer un simple serveur web dans une boucle principale personnalisée en python?

Idéalement, une solution ressemblera à ceci:

def main(): 
    """My main loop.""" 
    http_server = SomeCoolHttpServer(port=8888) 

    while True: 
     # Do my stuff here... 
     # ... 

     http_server.next() # Server gets it's turn. 

     # Do more of my stuff here... 
     # ... 

Répondre

7

Twisted est conçu pour faire des choses comme ça assez simple

import time 

from twisted.web import server, resource 
from twisted.internet import reactor 

class Simple(resource.Resource): 
    isLeaf = True 
    def render_GET(self, request): 
     return "<html>%s Iterations!</html>"%n 

def main(): 
    global n 
    site = server.Site(Simple()) 
    reactor.listenTCP(8080, site) 
    reactor.startRunning(False) 
    n=0 
    while True: 
     n+=1 
     if n%1000==0: 
      print n 
     time.sleep(0.001) 
     reactor.iterate() 

if __name__=="__main__": 
    main() 
+0

Comment ai-je su que Twisted allait apparaître? :) Cependant, votre exemple semble utiliser sa propre boucle principale. Comment puis-je contourner 'reactor.run()'? –

+0

Hm. Via , en ce qui concerne 'reactor.iterate()': "Le réacteur doit avoir été démarré (via le run (méthode) avant toute invocation de cette méthode, elle doit également être arrêtée manuellement après le dernier appel à cette méthode (via la méthode stop().) Cette méthode n'est pas réentrante: vous ne devez pas l'appeler récursivement, en particulier , vous ne devez pas l'appeler pendant que le réacteur fonctionne. " Est-ce ce que je cherche? –

+0

Oh, hé, je viens de remarquer que vous avez édité votre réponse. Merci d'avoir confirmé mes soupçons, et vous m'avez peut-être finalement convaincu de donner une autre chance à Twisted. :) –

-1

Je vous suggère de créer un nouveau thread et l'exécution d'un serveur Web (tel que SimpleHTTPServer intégré de Python ou BaseHTTPServer). Les threads ne sont vraiment pas si effrayants quand il s'agit de cela.

from threading import Event, Thread 
import BaseHTTPServer 

shut_down = Event() 

def http_server(): 
    server_address = ('', 8000) 
    httpd = BaseHTTPServer.HTTPServer(server_address, BaseHTTPServer.BaseHTTPRequestHandler) 

    while not shut_down.is_set(): 
     httpd.handle_request() 

thread = Thread(target=http_server) 
thread.start() 
+0

Vous devez être prudent - si les objets d'application que vous introspectez peuvent changer pendant que vous introspectez, une solution threadée va être très difficile à obtenir –

+0

C'est pourquoi je voudrais éviter le filetage. Merci. –

Questions connexes