Exemples

Les exemples ci-dessous décrivent un service complet : un serveur qui expose quelques méthodes arithmétiques, un client synchrone qui les appelle, un client qui parallélise plusieurs appels, et un client qui dialogue avec un serveur via TCP.

Exemple #1 Exemple de serveur Yar

Un service Yar est simplement une classe PHP ordinaire enveloppée par Yar_Server. Chaque méthode publique de l'objet devient un point d'entrée RPC ; les méthodes protégées et privées, ainsi que celles dont le nom commence par un tiret bas, restent cachées aux clients. Les commentaires de documentation des méthodes publiques sont collectés et affichés sur la page d'information du service.

Les requêtes RPC arrivent comme des requêtes HTTP POST portant un payload binaire au format du protocole Yar, donc le script est habituellement mappé à un URI sur un serveur web classique.

<?php

/* supposons que cette page soit accessible via http://api.example.com/operator.php */

class Operator {

    /**
     * Additionne deux opérandes
     * @param integer
     * @return integer
     */
    public function add($a, $b) {
        return $this->_add($a, $b);
    }

    /**
     * Sub
     */
    public function sub($a, $b) {
        return $a - $b;
    }

    /**
     * Mul
     */
    public function mul($a, $b) {
        return $a * $b;
    }

    /**
     * Les méthodes protégées ne seront pas exposées
     * @param integer
     * @return integer
     */
    protected function _add($a, $b) {
        return $a + $b;
    }
}

$server = new Yar_Server(new Operator());
$server->handle();
?>

Exemple #2 Accès au serveur depuis un navigateur (requête GET)

Lorsqu'une requête GET est envoyée à l'URI du service — par exemple en l'ouvrant dans un navigateur — Yar n'effectue pas d'appel RPC mais affiche une page d'information listant chaque méthode publique de l'objet exécuteur accompagnée de son commentaire de documentation. Ceci est contrôlé par la directive yar.expose_info ; quand elle est désactivée, une requête GET échoue à la place.

Résultat de l'exemple ci-dessus est similaire à :

Information du serveur Yar

Exemple #3 Exemple de client Yar

Un Yar_Client est lié à une seule adresse de service. Appeler n'importe quelle méthode non définie dessus est transparentement transformé en appel RPC synchrone, les méthodes distantes se comportant donc comme des méthodes locales ; Yar_Client::call() fait la même chose explicitement par nom.

Les méthodes protégées ne sont pas exposées : les appeler échoue avec une Yar_Client_Exception dont le code est YAR_ERR_REQUEST.

<?php
$client = new Yar_Client("http://api.example.com/operator.php");

/* appel direct */
var_dump($client->add(1, 2));

/* appel via call() */
var_dump($client->call("add", array(3, 2)));

/* _add ne peut pas être appelée : elle n'est pas publique */
var_dump($client->_add(1, 2));
?>

Résultat de l'exemple ci-dessus est similaire à :

int(3)
int(5)
PHP Fatal error:  Uncaught Yar_Client_Exception: call to undefined api Operator::_add() in *

Exemple #4 Exemple de client Yar concurrent

Au lieu d'appeler les services l'un après l'autre, Yar_Concurrent_Client enregistre d'abord plusieurs appels, puis les dispatch tous en même temps avec Yar_Concurrent_Client::loop(). Les réponses sont passées au callback dans l'ordre où elles arrivent, pas dans l'ordre où les appels ont été enregistrés.

Juste après que toutes les requêtes ont été envoyées, le callback est invoqué une fois avec des arguments null pour signaler à l'appelant qu'aucune requête n'est plus en attente ; l'exemple ci-dessous vérifie cette notification.

<?php
function callback($ret, $callinfo) {
    if ($callinfo == NULL) {
        /* toutes les requêtes ont été envoyées, en attente des réponses */
        return;
    }
    echo $callinfo['method'], " résultat : ", $ret, "\n";
}

function error_callback($type, $error, $callinfo) {
    error_log("[$type] $error");
}

/* enregistre les appels asynchrones vers les services distants */
Yar_Concurrent_Client::call("http://api.example.com/operator.php", "add", array(1, 2), "callback");
Yar_Concurrent_Client::call("http://api.example.com/operator.php", "sub", array(2, 1), "callback");
Yar_Concurrent_Client::call("http://api.example.com/operator.php", "mul", array(2, 2), "callback");

/* envoie toutes les requêtes et attend les réponses */
Yar_Concurrent_Client::loop("callback", "error_callback");
?>

Résultat de l'exemple ci-dessus est similaire à :

mul résultat : 4
sub résultat : 1
add résultat : 3

Exemple #5 Exemple de client Yar TCP

Outre HTTP, Yar_Client peut dialoguer avec des serveurs compatibles Yar via TCP ou des sockets Unix, par exemple un service implémenté avec le » framework Yar en C, qui utilise le même protocole binaire Yar que le serveur PHP.

<?php
$client = new Yar_Client("tcp://127.0.0.1:8600");

var_dump($client->add(1, 2));
?>
add a note

User Contributed Notes 1 note

up
-2
124960772 at qq dot com
10 years ago
<?php
function callback($ret, $callinfo) {
    echo $callinfo['method'] , " result: ", $ret , "\n";
}

/* 注册一个异步调用 */
Yar_Concurrent_Client::call("http://example.com/operator.php", "add", array(1, 2), "callback");
/* 发送所有注册的调用, 等待返回, 返回后Yar会调用callback回掉函数 */
Yar_Concurrent_Client::loop();
/* 重置call ,否则上面的call会调用*/
Yar_Concurrent_Client::reset();
Yar_Concurrent_Client::call("http://example.com/operator.php", "sub", array(2, 1), "callback");
Yar_Concurrent_Client::loop();

?>