Question

Je créé simple serveur RPC pour effectuer certaines tâches communes à nos équipes, mais qui sont appelés à partir de différents réseaux. Les regards du serveur comme celui-ci (je ne comprends pas le traitement des erreurs par souci de concision):

from twisted.internet.protocol import Protocol, Factory
from twisted.internet import reactor
import json

class MyProtocol(Protocol):
    def dataReceived(self, data):
        req = json.loads(data) # create a dictionary from JSON string
        method = getattr(self, req['method']) # get the method
        method(req['params']) # call the method

    def add(self, params):
        result = {} # initialize a dictionary to convert later to JSON
        result['result'] = sum(params) 
        result['error'] = None 
        result['id'] = 1
        self.transport.write(json.dumps(result)) # return a JSON string
        self.transport.loseConnection() # close connection

factory = Factory()
factory.protocol = MyProtocol
reactor.listenTCP(8080, factory)
reactor.run()

Ceci est très simple: le serveur reçoit une demande JSON RPC du client, recherche la méthode, et appelle la méthode passer les paramètres. Le procédé lui-même est l'une de retourner la réponse JSON RPC. Pour les moins familiers, un JSON RPC ressemble à peu près comme ceci:

request:
{"method":"my_method", "params":[1,2,3], "id":"my_id"}
response:
{"result":"my_result", "error":null, "id":"my_id"}

Le serveur RPC comme je l'ai sert très bien mes actuels fins (comme vous pouvez l'imaginer, ma tâche est très simple). Mais je vais devoir continuer à ajouter des méthodes comme la complexité de la tâche augmente.

Je ne veux pas ouvrir le fichier principal et ajouter une autre def method3(...) et, deux semaines plus tard, ajouter def method4(...) et ainsi de suite; le code grandirait trop rapidement et l'entretien serait plus difficile et plus dur.

Alors, ma question est: Comment puis-je créer une architecture qui me permet de enregistrer méthodes dans le serveur . Un bonus serait d'avoir un dossier distinct tenant un fichier par méthode, de sorte qu'ils peuvent facilement être partagés et entretenus. Cette « architecture » me permettrait également de reporter l'entretien de certaines méthodes à quelqu'un d'autre, quelle que soit leur compréhension de Twisted.

Je ne se soucient pas si je dois redémarrer le serveur à chaque fois est enregistré une nouvelle méthode, mais une évidence, plus serait si je ne pas ont trop:).

Merci.

Était-ce utile?

La solution

Un peu d'un ordre assez grand;) mais voici quelques premières étapes pour vous (très fortement moqué-up, les spécificités tordues ommited dans les exemples):

# your twisted imports...
import json

class MyProtocol(object): # Would be Protocol instead of object in real code

    def dataReceived(self, data):
        req = json.loads(data) # create a dictionary from JSON string
        modname, funcname = req['method'].split('.')
        m = __import__(modname)
        method = getattr(m, funcname) # get the method
        method(self, req['params']) # call the method

En supposant que vous l'essayer comme si nous avons exécuté ceci:

mp = MyProtocol()
mp.dataReceived('{"method":"somemod.add", "params":[1,2,3]}')

Wold ont un somemod.py de module dans le même répertoire que l'exemple avec le contenu suivant (Mirroring ci-dessus votre exemple méthode .add()):

import json

def add(proto, params):
    result = {} # initialize a dictionary to convert later to JSON
    result['result'] = sum(params)
    result['error'] = None
    result['id'] = 1
    proto.transport.write(json.dumps(result)) # return a JSON string
    proto.transport.loseConnection() # close connection

Cela vous permet d'avoir un module par méthode servi. Ce qui précède appel method(.. toujours passer votre instance de MyProtocol à la appelable servir. (Si vous voulez vraiment des méthodes d'instance, voici des instructions sur la façon d'ajouter des méthodes à l'aide de python: http: // irrepupavel .com / documents / python / instancemethod / )

Vous aurez besoin de beaucoup de traitement des erreurs ajouté. Par exemple, vous avez besoin de beaucoup de contrôle d'erreur à l'appel split() sur la ligne 2 de dataReceived().

Avec cela, vous pouvez avoir des fichiers séparés avec une fonction en eux pour toutes les méthodes dont vous avez besoin au soutien. En aucun cas, un exemple complet, mais il peut vous aider à aller, puisque ce your'e recherche est assez complexe.

Pour un enregistrement plus formel, je vous recommande un dict en MyProtocol avec les noms des méthodes que vous soutenez, le long des lignes de:

# in MyProtocol's __init__() method:
self.methods = {}

Et une méthode de registre ..

def register(self, name, callable):
    self.methods[name] = callable

.. modifier dataReceived() ..

def dataReceived(self, data):
    # ...
    modname, funcname = self.methods.get(req['method'], False)
    # ..continue along the lines of the dataReceived() method above

Résumé rapide d'un poste trop longtemps: la fonction __import__ ( http: //docs.python .org / bibliothèque / functions.html ) sera très certainement un élément clé de votre solution.

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