Frage

habe ich eine einfache RPC Server bestimmte Aufgaben gemeinsam unsere Teams erfüllen, aber die werden aus verschiedenen Netzwerken genannt. Der Server sieht wie folgt aus (I enthalten keine Fehlerbehandlung der Kürze halber):

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()

Das ist sehr einfach: der Server eine JSON-RPC-Anforderung von dem Client, sucht nach der Methode empfängt, und ruft die Methode die Parameter übergeben. Das Verfahren selbst ist die, die JSON RPC-Antwort zurück. Für die weniger vertraut, ein JSON-RPC sieht etwa wie folgt aus:

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

Der RPC-Server, wie ich habe es sehr gut meine aktuellen Zwecken dient (wie man sich vorstellen kann, ist meine Aufgabe sehr einfach). Aber ich werde auch weiterhin brauchen, um Methoden wie die Komplexität der Aufgabe erhöht hinzuzufügen.

Ich will nicht die Haupt-Datei öffnen, und fügen Sie noch eine weitere def method3(...) und zwei Wochen später, fügen def method4(...) und so weiter; der Code würde zu schnell wachsen und die Wartung schwieriger und schwieriger wäre.

Also, meine Frage ist: Wie kann ich eine Architektur schaffen, die mir erlaubt, zu registrieren Methoden in den Server . Ein Bonus wäre, einen separaten Ordner haben, eine Datei pro Methode zu halten, so dass sie leicht ausgetauscht werden können und gepflegt. Diese „Architektur“ würde mir erlauben, auch aufzuschieben Wartung einiger Methoden an jemand anderen, unabhängig von ihrem Verständnis von Verdrehte.

ist mir egal, wenn ich brauche den Server jedes Mal eine neue Methode zum Neustart registriert ist, aber ein deutliches Plus wäre, wenn ich nicht haben auch:).

Danke.

War es hilfreich?

Lösung

Bit A eine largish Ordnung;) aber hier einige ersten Schritte für Sie (sehr stark verspottet-up, verdrehte Besonderheiten in den Beispielen ommited):

# 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

Angenommen, Sie probieren Sie es aus, als ob wir diese ausgeführt:

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

Sie Wold ein Modul somemod.py im selben Verzeichnis wie das Beispiel mit dem folgenden Inhalt haben (Mirroring Ihr Beispiel Methode .add() oben):

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

Auf diese Weise können Sie ein Modul pro Methode bedient haben. Der method(.. Anruf oben wird immer Ihre MyProtocol Instanz an die versorgende aufrufbar passieren. (Wenn Sie wirklich Instanzmethoden wollen, ist hier Anweisungen, wie Methoden hinzufügen Python mit: http: // irrepupavel .com / documents / python / instancemethod / )

Sie werden eine Menge von Fehlerbehandlung benötigen hinzugefügt. Zum Beispiel müssen Sie eine Menge von Fehlerprüfung an der split() Anruf auf Leitung 2 von dataReceived().

Mit diesem können Sie verfügen über separate Dateien mit einer Funktion in ihnen für jede Methode, die Sie Unterstützung benötigen. Keineswegs ein vollständiges Beispiel, aber es könnte loslegen Sie, da das, was suchen your'e für recht komplex ist.

Für eine formelle Registrierung, würde ich einen dict in MyProtocol mit Namen von Methoden empfehlen, dass Sie unterstützen, entlang der Linien von:

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

Und ein Register Methode ..

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

.. ändern dataReceived() ..

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

Kurze Zusammenfassung eines zu langen Beitrag: die __import__ Funktion ( http: //docs.python .org / library / functions.html ) wird mit Sicherheit ein wichtiger Teil Ihrer Lösung sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top