⇤ ← Revision 1 as of 2009-04-09 07:16:15
Size: 6295
Comment:
|
Size: 6694
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 55: | Line 55: |
class TCPClient(FakeRmt) Semplice classe client che eredita da FakeRmt. Si usa tipo: a = TCPClient('192.168.1.1',8888) ret = a.rpc_call('nomefunc', (1,)) ret = a.nomefunc(1) Funziona a patto che il blob prodotto da rencode per nomefunc e parametri non superi 1024 bytes e lo stesso per il valore ritornato. Alla chiamata di un metodo, si collega al MicroTCPServer remoto, invia in un blob il nome del metodo e gli argomenti, aspetta la risposta in un blob dal host remoto, la decodifica (la risposta può essere anche una eccezione) e la resituisce, terminando, al chiamante. |
'''~+{{{class TCPClient(FakeRmt)}}}+~''' |
Line 63: | Line 57: |
Semplice classe client che eredita da {{{FakeRmt}}}. Si usa tipo: <<BR>> {{{ a = TCPClient('192.168.1.1',8888)}}} <<BR>> --({{{ ret = a.rpc_call('nomefunc', (1,))}}})-- <<BR>> {{{ ret = a.nomefunc(1)}}} <<BR>> --(Funziona a patto che il blob prodotto da rencode per nomefunc e parametri non superi 1024 bytes e lo stesso per il valore ritornato.)-- <<BR>> Alla chiamata di un metodo, si collega al {{{MicroTCPServer}}} remoto, invia in un blob il nome del metodo e gli argomenti, aspetta la risposta in un blob dal host remoto e la decodifica (la risposta può essere anche una eccezione). Poi il metodo termina restituendo la risposta al chiamante. |
|
Line 64: | Line 69: |
Le microfunc micro_dgram_request_handler e UDPServer sono le analoghe di micro_stream_request_handler e TCPServer in versione UDP broadcast. La MicroUDPServer viene richiamata passando la root_instance. Si istanza un RPCDispatcher e poi riceve i pacchetti (recvfrom(8192)) da un socket "stackless-wrapped" di tipo datagram, di default bindato alla porta 269 di tutte le interfacce di rete. Con ogni pacchetto che riceve richiama la microfunc micro_dgram_request_handler e subito torna in ascolto. Questa microfunc a) popola la classe CallerInfo con i dati del chiamante, b) decodifica il pacchetto con _data_unpack_from_buffer, c) richiama la marshalled_dispatch del RPCDispatcher passando il blob e il CallerInfo. |
'''~+{{{MicroUDPServer(...)}}}+~''' |
Line 68: | Line 71: |
class BcastClient(FakeRmt) Semplice classe client analoga di TCPClient in versione UDP broadcast. La classe BcastClient si usa tipo: a = BcastClient() # si può passare un elenco di interfacce a.nomeFunc(3,2) # nulla viene ritornato |
Le microfunc '''{{{micro_dgram_request_handler}}}''' e '''{{{MicroUDPServer}}}''' sono le analoghe di {{{micro_stream_request_handler}}} e {{{MicroTCPServer}}} in versione UDP broadcast. <<BR>> La '''{{{MicroUDPServer}}}''' viene richiamata passando la root_instance. Si istanzia un {{{RPCDispatcher}}} e poi riceve i pacchetti (''{{{recvfrom(8192)}}}'') da un socket "stackless-wrapped" di tipo datagram, di default bindato alla porta 269 di tutte le interfacce di rete. Con ogni pacchetto che riceve richiama la microfunc '''{{{micro_dgram_request_handler}}}''' e subito torna in ascolto. <<BR>> Questa microfunc a) popola la classe '''{{{CallerInfo}}}''' con i dati del chiamante, b) decodifica il pacchetto con '''{{{_data_unpack_from_buffer}}}''', c) richiama la {{{marshalled_dispatch}}} del {{{RPCDispatcher}}} passando il blob e il {{{CallerInfo}}}. '''~+{{{class BcastClient(FakeRmt)}}}+~''' Semplice classe client analoga di {{{TCPClient}}} in versione UDP broadcast. <<BR>> La classe {{{BcastClient}}} si usa tipo: <<BR>> {{{ a = BcastClient() # si può passare un elenco di interfacce}}} <<BR>> {{{ a.nomeFunc(3,2) # nulla viene ritornato}}} <<BR>> |
Line 74: | Line 88: |
<<BR>> | |
Line 75: | Line 90: |
<<BR>> | |
Line 77: | Line 93: |
Esiste una testsuite per il modulo. Come è usato il modulo rpc in Netsukuku |
Vedi anche [[../UsoDelModuloRPCInNetsukuku|come viene usato il modulo rpc in Netsukuku]]. |
Il modulo RPC
class NtkRPCDispatcher(object) class RPCDispatcher(object)
Un'istanza della classe RPCDispatcher registra con il metodo register_function le funzioni (indicizzandole per nome) e fornisce il metodo marshalled_dispatch(data) per richiamare le funzioni definite remotable sulla base di un blob (arrivato via rete) che codifica (tramite rencode - vedi il modulo rencode) nome-funzione e parametri.
Lato server è sufficiente che le funzioni abbiano il nome in remotable_funcs (nelle globals o in una classe di cui sono metodo)
SocketServer.BaseRequestHandler
Base class for request handler classes.
This class is instantiated for each request to be handled. The constructor sets the instance variables request, client_address and server, and then calls the handle() method. To implement a specific service, all you need to do is to derive a class which defines a handle() method.
The handle() method can find the request as self.request, the client address as self.client_address, and the server (in case it needs access to per-server information) as self.server. Since a separate instance is created for each request, the handle() method can define arbitrary other instance variariables.
SocketServer.TCPServer (SocketServer.BaseServer)
Base class for various socket-based server classes.
Defaults to synchronous IP stream (i.e., TCP).
Methods for the caller:
__init__(server_address, RequestHandlerClass)
serve_forever()
class StreamRequestHandler(SocketServer.BaseRequestHandler)
class TCPServer(SocketServer.TCPServer, RPCDispatcher)
La classe StreamRequestHandler ereditando BaseRequestHandler fornisce un hook nel metodo handle() per gestire una richiesta. Viene overridato per a) popolare la classe CallerInfo con i dati del chiamante e b) richiamare la marshalled_dispatch del server passando questi dati.
La classe TCPServer eredita sia da TCPServer sia da RPCDispatcher e nel suo costruttore usa come gestore predefinito StreamRequestHandler. In questo modo quando si crea una istanza - e.g. server = TCPServer(ntkd, ('localhost', 8888)) - si ha un server che permette di richiamare funzioni quando viene ricevuta una richiesta (metodo handle).
Inoltre si ha un indirizzo predefinito che è ('localhost', 269) - quindi si può usare server = TCPServer(ntkd) - ascolta tutto sulla 269.
MicroTCPServer(...)
La microfunc di modulo MicroTCPServer viene richiamata passando la cosidetta root_instance, cioè la classe con le remotable_funcs, che di norma è la stessa istanza di NtkNode che fa da collante tra i vari moduli (vedi la classe NtkNode).
Si istanzia un RPCDispatcher e poi sta in ascolto su un socket "stackless-wrapped", di default bindato alla porta 269 di tutte le interfacce di rete. Per ogni connessione che riceve richiama la microfunc micro_stream_request_handler e subito torna in ascolto.
Questa microfunc a) popola la classe CallerInfo con i dati del chiamante, b) legge dal socket il messaggio in un blob con _data_unpack_from_stream_socket, c) richiama la marshalled_dispatch del RPCDispatcher passando il blob e il CallerInfo, d) rinvia al socket la risposta ottenuta dal RPCDispatcher inpacchettandola con _data_pack.
class FakeNtkd() class FakeRmt()
E' una classe che permette di chiamare una RPC con una sintassi identica alla chiamata di un metodo locale.
Ad esempio remote_instance.mymethod1.mymethod2.func(p1, p2, p3)
invece di remote_instance.rmt('mymethod1.method2.func', (p1, p2, p3))
In realtà il metodo rmt va implementato in una derivata di questa classe, con in esso la effettiva chiamata RPC.
class TCPClient(FakeRmt)
Semplice classe client che eredita da FakeRmt. Si usa tipo:
a = TCPClient('192.168.1.1',8888)
ret = a.rpc_call('nomefunc', (1,))
ret = a.nomefunc(1)
Funziona a patto che il blob prodotto da rencode per nomefunc e parametri non superi 1024 bytes e lo stesso per il valore ritornato.
Alla chiamata di un metodo, si collega al MicroTCPServer remoto, invia in un blob il nome del metodo e gli argomenti, aspetta la risposta in un blob dal host remoto e la decodifica (la risposta può essere anche una eccezione). Poi il metodo termina restituendo la risposta al chiamante.
MicroUDPServer(...)
Le microfunc micro_dgram_request_handler e MicroUDPServer sono le analoghe di micro_stream_request_handler e MicroTCPServer in versione UDP broadcast.
La MicroUDPServer viene richiamata passando la root_instance. Si istanzia un RPCDispatcher e poi riceve i pacchetti (recvfrom(8192)) da un socket "stackless-wrapped" di tipo datagram, di default bindato alla porta 269 di tutte le interfacce di rete. Con ogni pacchetto che riceve richiama la microfunc micro_dgram_request_handler e subito torna in ascolto.
Questa microfunc a) popola la classe CallerInfo con i dati del chiamante, b) decodifica il pacchetto con _data_unpack_from_buffer, c) richiama la marshalled_dispatch del RPCDispatcher passando il blob e il CallerInfo.
class BcastClient(FakeRmt)
Semplice classe client analoga di TCPClient in versione UDP broadcast.
La classe BcastClient si usa tipo:
a = BcastClient() # si può passare un elenco di interfacce
a.nomeFunc(3,2) # nulla viene ritornato
Alla chiamata di un metodo, si prepara un messaggio codificando in un blob il nome del metodo e gli argomenti.
Il messaggio è inviato in broadcast via tutte le interfacce di rete (o quelle richieste). Non si attende una risposta ma si fa subito ritorno al chiamante.
La versione broadcast (UDP) del rpc funziona solo per messaggi inferiori a 8 kB (when packed)
Vedi anche come viene usato il modulo rpc in Netsukuku.