JSON-RPC-PHP: accesso remoto ad una classe

Introduzione

Può capitare di aver bisogno di eseguire di avviare da una macchina locale l’esecuzione di codice su un’altra macchina.

È il concetto di RPC (Remote Procedure Call).

In questo articolo cercheremo di realizzare una RPC generica scritta in PHP e basata su JSON. Cercheremo, in particolare, di fare in modo che il lato client della RPC veda veramente il lato server come se fosse una classe di oggetti locale, quindi con oggetti che possono essere istanziati e il cui stato può essere modificato nel corso dell’esecuzione.

Per ottenere questo risultato attraverso la rete, utilizzeremo le sessioni HTTP.

Il lato server

Una classe di esempio

Supponiamo di voler usare una semplice classe «lampadina» che risiede su una macchina remota.

Il server

Con la classe che segue, vogliamo rispondere a diverse chiamate:

Creazione dell’oggetto:

Richiesta di un metodo:

Sia alla creazione che alla richiesta di un metodo, i parametri da passare alla classe vengono raccolti come array.

Queste funzioni sono realizzate dal seguente programma:

La risposta fornita sulla rete è fatta di un header HTTP e due campi.

L’header HTTP ci informa sull’esito della chiamata, distinguendo soprattutto i successi (200) dai fallimenti (tutti gli altri codici).

Il campo content contiene la variabile restituita con return.

Il campo bufferedOutput contiene tutto l’output che potrebbe essere emesso dai metodi della classe (ad esempio con degli echo).

Limiti di questa soluzione

Non tutte le classi possono essere trattate così semplicemente. Il punto delicato è la serializzazione dell’oggetto, che produce la perdita delle proprietà di tipo risorsa.

Non è poco. Le risorse sono quelle attraverso cui apriamo connessioni ai database, leggiamo e scriviamo su file, operiamo connessioni di rete, ecc. (Vedi: PHP, List of Resource Types.)

Se vogliamo utilizzare delle classi che trattano delle risorse, dobbiamo adattarle e arricchirle con metodi __sleep() e __wakeup() (l’esempio del manuale è relativo proprio a questo).
Ancora più ordinato sarebbe richiedere che le classi coinvolte implementino la Serializable Interface e introdurre nel server una verifica con l’operatore instanceof.

Analogamente, se la variabile restituita è un oggetto, la sua trasformazione (con json_encode(), ma lo stesso avverrebbe con qualsiasi sistema di serializzazione) tutti i suoi metodi andranno perduti.

Per ovviare a questo problema, l’unica soluzione è migliorare il server in modo da poter ricostruire l’oggetto serializzato con… un’altra chiamata!

Il lato client

La classe client

La lettura e l’interpretazione del server viene fatto da questa classe:

La classe, ad eccezione del costruttore, si comporterà esattamente come l’oggetto remoto (salvo nei casi elencati tra le limitazioni).

Esempio

Un server pubblico

Chi vuole, può provare un class server (con la sola lampadina) disponibile a: http://inservibile.org/php/classServer.php (attenzione all’header Content-type: application/json )

Eccolo in funzione.

[php snippet=1]

Non fa molto effetto a vederlo… 🙂 ma il testo qui in alto viene costruito utilizzando proprio quel server remoto e il programma dell’esempio.

Conclusioni

Il PHP è stato utilizzato su entrambi i lati solo per questioni di comodo.

Rispettando le logiche di questa soluzione, infatti, possiamo scrivere il codice sui due lati con linguaggi diversi, intendere la soluzione solo come protocollo e concepire questo sistema anche come metodo di scambio di funzionalità tra linguaggi diversi (es. .NET e Java).

Un modello concettuale spesso utilizzato per descrivere le RPC è proprio quello delle classi di oggetti. Ma le soluzioni in voga (REST/JSON, SOAP, ecc.) in realtà esauriscono tutto il processo in un’unica chiamata. Qui invece possiamo utilizzare un web service per simulare davvero l’uso di una classe locale, mentre il codice viene eseguito in un sistema remoto.

Questa logica può essere necessaria per diverse ragioni: perché il codice remoto è sofisticato e affidabile, perché deve essere utilizzato da più macchine client, perché dalla macchina locale si vuole modificare lo stato della macchina remota, perché si vuole realizzare interoperabilità tra linguaggi.

Buon lavoro.

Leave a Comment

Your email address will not be published.

Analisi degli accessi a www.istat.it
×
', 'auto'); ga('require', 'displayfeatures'); ga('set', 'forceSSL', true); ga('send', 'pageview');