Question

J'ai une application web Django. J'ai aussi un serveur sort écrit en utilisant la course tordue sur la même machine ayant django (en cours d'exécution sur localhost:8090). L'idée étant lorsque l'utilisateur fait une action, la demande vient de Django qui se connecte à son tour à ce serveur et serveur torsadé envoie des données à Django. Enfin Django met ces données dans un certain modèle et sert html il à l'utilisateur.

Voici où j'ai un problème. Dans mon application Django, lorsque la demande vient créer un client simple tordu pour se connecter au serveur torsadé exécuter localement.

...
        factory = Spell_Factory(query) 
        reactor.connectTCP(AS_SERVER_HOST, AS_SERVER_PORT, factory)
        reactor.run(installSignalHandlers=0)
        print factory.results
...

Le reactor.run() est à l'origine d'un problème. Comme il est une boucle d'événements. La prochaine fois que ce même code est exécuté par Django, je suis incapable de se connecter au serveur. Comment peut-on gérer cela?

Était-ce utile?

La solution

Les deux réponses ci-dessus sont corrects. Cependant, étant donné que vous avez déjà mis en place une orthographe serveur puis Exécuter comme un . Vous pouvez commencer par exécuter sur la même machine comme un processus séparé - à localhost:PORT. À l'heure actuelle, il semble que vous avez une interface de protocole binaire très simple déjà -. Vous pouvez mettre en œuvre un client Python tout aussi simple en utilisant l'interface standard socket de lib en mode bloquant

Cependant, je vous suggère de jouer avec twisted.web et d'exposer une interface web simple. Vous pouvez utiliser JSON aux données de sérialisation et la désérialisation - qui est bien pris en charge par Django. Voici un exemple très rapide:

import json
from twisted.web import server, resource
from twisted.python import log

class Root(resource.Resource):
    def getChild(self, path, request):
        # represents / on your web interface
        return self

class WebInterface(resource.Resource):
    isLeaf = True
    def render_GET(self, request):
        log.msg('GOT a GET request.')
        # read request.args if you need to process query args
        # ... call some internal service and get output ...
        return json.dumps(output)

class SpellingSite(server.Site):
    def __init__(self, *args, **kwargs):
        self.root = Root()
        server.Site.__init__(self, self.root, **kwargs)
        self.root.putChild('spell', WebInterface())

Et pour l'exécuter, vous pouvez utiliser le fichier squelette .tac suivant:

from twisted.application import service, internet

site = SpellingSite()
application = service.Application('WebSpell')
# attach the service to its parent application
service_collection = service.IServiceCollection(application)
internet.TCPServer(PORT, site).setServiceParent(service_collection)

L'exécution de votre service comme un autre service de première classe vous permet d'exécuter sur une autre machine si un jour vous trouvez la nécessité -. Exposer une interface web rend l'échelle facile à l'horizontale derrière un équilibreur de charge inverse de mandatement trop

Autres conseils

reactor.run() devrait être appelé une seule fois dans votre programme. Ne pensez pas comme « commencer celui-ci demande que j'ai », pensez comme « commencer tous Twisted ».

Exécution du réacteur dans un thread d'arrière-plan est un moyen de contourner ce; alors votre application django peut utiliser blockingCallFromThread dans votre application Django et utiliser une API Twisted comme vous API bloquer tout. Vous aurez besoin d'un peu de coopération de votre conteneur WSGI, cependant, parce que vous devez vous assurer que ce fond fil torsadé est démarré et arrêté à des moments appropriés (lorsque votre interprète est initialisé et démolie, respectivement).

Vous pouvez également utiliser Twisted comme contenant WSGI, et vous n'avez pas besoin pour démarrer ou arrêter quelque chose de spécial; blockingCallFromThread va juste travailler immédiatement. Consultez l'aide en ligne de commande pour twistd web --wsgi.

Vous devriez arrêter réacteur après avoir obtenu des résultats à partir du serveur Twisted ou un événement d'erreur / délai d'attente. Ainsi, sur chaque demande Django qui nécessite requête serveur Twisted vous devez exécuter réacteur, puis l'arrêter. Mais, ce n'est pas pris en charge par la bibliothèque Twisted - réacteur n'est pas redémarrant. Solutions possibles:

  • Utilisez du fil séparé pour le réacteur Twisted, mais vous devez déployer votre application django avec le serveur, qui supporte les longs fils en cours d'exécution (je ne maintenant toutes ces choses, mais vous pouvez écrire votre propre facilement: -.))

  • Ne pas utiliser Twisted pour mettre en œuvre le protocole client, il suffit d'utiliser le module de socket stdlib plaine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top