Ejemplos

Los ejemplos siguientes recorren un servicio completo: un servidor que expone algunos métodos aritméticos, un cliente síncrono que los llama, un cliente que lanza varias llamadas de forma concurrente y un cliente que se comunica con un servidor por TCP.

Ejemplo #1 Ejemplo de servidor Yar

Un servicio Yar no es más que una clase PHP normal envuelta por Yar_Server. Cada método público del objeto se convierte en un punto de acceso RPC; los métodos protegidos y privados, así como los métodos cuyo nombre empieza por un guion bajo, permanecen ocultos para los clientes. Los comentarios de documentación de los métodos públicos se recopilan y se muestran en la página de información del servicio.

Las peticiones RPC llegan como peticiones HTTP POST que transportan una carga útil binaria del protocolo Yar, por lo que el script suele asociarse a un URI de un servidor web normal.

<?php

/* se supone que esta página es accesible en http://api.example.com/operator.php */

class Operator {

    /**
     * Suma dos operandos
     * @param integer
     * @return integer
     */
    public function add($a, $b) {
        return $this->_add($a, $b);
    }

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

    /**
     * Multiplicación
     */
    public function mul($a, $b) {
        return $a * $b;
    }

    /**
     * Los métodos protegidos no se exponen
     * @param integer
     * @return integer
     */
    protected function _add($a, $b) {
        return $a + $b;
    }
}

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

Ejemplo #2 Acceso al servidor desde el navegador (petición GET)

Cuando se emite una petición GET al URI del servicio, por ejemplo al abrirlo en un navegador, Yar no realiza una llamada RPC, sino que muestra una página de información que lista todos los métodos públicos del objeto ejecutor junto con su comentario de documentación. Esto se controla con la directiva yar.expose_info; cuando está desactivada, la petición GET falla en su lugar.

Resultado del ejemplo anterior es similar a:

Yar Server Info

Ejemplo #3 Ejemplo de cliente Yar

Un Yar_Client está asociado a una única dirección de servicio. Llamar a cualquier método no definido sobre él se convierte de forma transparente en una llamada RPC síncrona, de modo que los métodos remotos se ven y se usan como si fueran locales; Yar_Client::call() hace lo mismo indicando el nombre de forma explícita.

Los métodos protegidos no se exponen: llamar a uno de ellos falla con una Yar_Client_Exception cuyo código es YAR_ERR_REQUEST.

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

/* llamada directa */
var_dump($client->add(1, 2));

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

/* _add no se puede llamar: no es público */
var_dump($client->_add(1, 2));
?>

Resultado del ejemplo anterior es similar a:

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

Ejemplo #4 Ejemplo de cliente concurrente Yar

En lugar de llamar a los servicios uno tras otro, Yar_Concurrent_Client registra primero varias llamadas y luego las envía todas a la vez con Yar_Concurrent_Client::loop(). Las respuestas se pasan al callback en el orden en que llegan, no en el orden en que se registraron las llamadas.

Justo después de que se hayan enviado todas las peticiones, el callback se invoca una vez con argumentos null para que quien lo llama sepa que no queda ninguna petición pendiente; el ejemplo siguiente comprueba esta notificación.

<?php
function callback($ret, $callinfo) {
    if ($callinfo == NULL) {
        /* todas las peticiones se han enviado, esperando las respuestas */
        return;
    }
    echo $callinfo['method'], " resultado: ", $ret, "\n";
}

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

/* registra llamadas asíncronas a servicios remotos */
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");

/* envía todas las peticiones y espera las respuestas */
Yar_Concurrent_Client::loop("callback", "error_callback");
?>

Resultado del ejemplo anterior es similar a:

mul resultado: 4
sub resultado: 1
add resultado: 3

Ejemplo #5 Ejemplo de cliente TCP Yar

Además de HTTP, Yar_Client puede comunicarse con servidores compatibles con Yar a través de TCP o de sockets Unix, por ejemplo con un servicio implementado con el » framework Yar en C, que sirve el mismo protocolo binario de Yar que usa el servidor 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();

?>