2009-09-10 5 views
2

je le fonctionnement du serveur suivant:bonne façon d'écrire une fonction de client léger à importer Twisted Python

class ThasherProtocol(basic.LineReceiver): 
    def lineReceived(self, line): 
     dic = simplejson.loads(line) 
     ret = self.factory.d[ dic['method'] ](dic['args']) 
     self.transport.write(simplejson.dumps(ret)) 
     self.transport.loseConnection() 



class ThasherFactory(ServerFactory): 
    protocol = ThasherProtocol 

    def __init__(self): 
     self.thasher = Thasher() 
     self.d= { 
      'getHash': self.thasher.getHash, 
      'sellHash' : self.thasher.sellHash 
      } 


reactor.listenUNIX(c.LOCATION_THASHER, ThasherFactory()) 
reactor.run() 

J'ai plusieurs fichiers importer une fonction spéciale appelée « getHash » à partir d'un fichier particulier. Notez que les arguments de getHash ne seront qu'un dictionnaire de textes (chaînes de caractères). Comment puis-je écrire une fonction client (getHash) qui peut être simplement:

from particular file import getHash 
i = getHash({ 'type':'url', 'url':'http://www.stackoverflow.com' }) 

Notez que TOUT CE QUE JE VEUX FAIRE est: 1) de jeter un dict en JSON, 2) Dump JSON dans le particulier socket, 3) attendez que cela revienne et déballez le json

+0

En fait, si je ne ferme pas la connexion et le maintenir n'y aurait-il pas encore plus rapide parce que je ne ai pas besoin de se connecter et d'arrêt à chaque fois –

+0

Mais la la partie difficile de cela est qu'il y aura plusieurs fichiers source en utilisant cette fonction, donc je ne sais pas comment je le fais à travers différents fichiers –

Répondre

2

Vous voulez getHash pour retourner un Deferred, pas une valeur synchrone.

Pour ce faire, créez un Deferred et associez-le à la connexion qui effectue une requête particulière.

Ce qui suit est non testé et ne fonctionnera probablement pas, mais il devrait vous donner une idée approximative:

import simplejson 
from twisted.python.protocol import ClientFactory 
from twisted.internet.defer import Deferred 
from twisted.internet import reactor 
from twisted.protocols.basic import LineReceiver 

class BufferingJSONRequest(LineReceiver): 
    buf = '' 

    def connectionMade(self): 
     self.sendLine(simplejson.dumps(self.factory.params)) 

    def dataReceived(self, data): 
     self.buf += data 

    def connectionLost(self, reason): 
     deferred = self.factory.deferred 
     try: 
      result = simplejson.load(self.buf) 
     except: 
      deferred.errback() 
     else: 
      deferred.callback(result) 

class BufferingRequestFactory(ClientFactory): 
    protocol = BufferingJSONRequest 

    def __init__(self, params, deferred): 
     self.params = params 
     self.deferred = deferred 

    def clientConnectionFailed(self, connector, reason): 
     self.deferred.errback(reason) 

def getHash(params): 
    result = Deferred() 
    reactor.connectUNIX(LOCATION_THASHER, 
         BufferingRequestFactory(params, result)) 
    return result 

Maintenant, pour utilisation cette fonction, vous aurez déjà besoin de se familiariser avec Différé, et vous aurez besoin d'écrire une fonction de rappel à exécuter lorsque le résultat arrive finalement. Mais une explication de ceux-ci appartient à une question séparée;).

+0

Oui merci. Mais si cela prend moins d'un millionième de seconde, est-il vraiment nécessaire de renvoyer un différé? Est-ce que le fait de renvoyer un différé ne serait pas juste une exagération? Puis-je faire cela sans report? (Notez que je l'utilise plus de quelques millions de fois par essai et je dois vraiment réduire les parties inutiles.) –

+0

En fait, j'ai consulté les gens de #twisted et la conclusion est qu'ils ne pensent pas tordu est vraiment ce que je cherche. Je ne peux pas lancer reactor.run sur mon client car reactor.run bloque –

+1

Les différés ne concernent pas les choses qui prennent un * temps * long, mais une durée * variable *. Si vous avez besoin de faire 1000 requêtes, la plupart d'entre elles prendront très peu de temps (bien que probablement pas aussi petit qu'un millionième de seconde, plus comme quelques millièmes) mais dix d'entre elles prendront 25 secondes à cause d'un réseau bizarre problème de congestion que vous ne pouvez pas prédire. Si vous êtes assis là et attendez que chaque demande revienne, votre programme sera lent et gèle tout le temps, même si "la plupart du temps" l'appel est rapide. – Glyph

-1

J'ai réussi à résoudre mon propre problème.

Utiliser des douilles (prises Unix en particulier) ça accélère mon application 4x et ce n'est pas difficile à utiliser du tout.

maintenant ma solution est simplejson + prise

+0

Semble tordu était trop lourd pour ce que vous essayiez de faire. –

Questions connexes