Maison  >  Article  >  développement back-end  >  Comment implémenter un simple client RPC en utilisant PHP

Comment implémenter un simple client RPC en utilisant PHP

PHPz
PHPzoriginal
2023-04-24 14:53:00765parcourir

RPC (Remote Procedure Call) est un protocole de communication informatique qui permet à un programme d'appeler un sous-programme dans un autre espace ou une autre machine. Ce protocole nous permet d'appeler des fonctions dans des services distants au même titre que des fonctions locales, à condition d'implémenter le client et le serveur du protocole RPC.

Cet article présentera comment implémenter un RPC simple en utilisant PHP Nous utiliserons le protocole JSON-RPC, qui est un protocole léger et simple.

  1. Préparation

Avant de commencer à écrire du code, nous devons connaître les éléments suivants :

  • Qu'est-ce que le protocole JSON-RPC et quelles sont ses caractéristiques ?
  • Programmation de socket PHP, notamment l'utilisation de sockets.
  • Analyse et sérialisation JSON pour PHP.
  1. PHP implémente un simple client RPC

Nous pouvons utiliser PHP pour implémenter un simple client RPC, qui est responsable de l'envoi des requêtes et de la réception des réponses. Son workflow est le suivant :

  • Créer une prise socket.
  • Utilisez la fonction socket_create() pour créer un socket.
  • Utilisez la fonction socket_connect() pour vous connecter au serveur.
  • Envoyez les informations de la demande au serveur.
  • Utilisez la fonction socket_read() pour lire les résultats renvoyés par le serveur.

Ce qui suit est un exemple d'implémentation :

class RpcClient
{
    private $url;
    private $port;
    private $timeout;
    private $socket;

    public function __construct($url, $port, $timeout = 30)
    {
        $this->url = $url;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->connect();
    }

    private function connect()
    {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($this->socket === false) {
            throw new Exception("unable to create socket: " . socket_strerror(socket_last_error()));
        }
        $result = socket_connect($this->socket, $this->url, $this->port);
        if ($result === false) {
            throw new Exception("unable to connect socket: " . socket_strerror(socket_last_error()));
        }
    }

    public function call($function_name, $parameters = [])
    {
        $request_body = json_encode([
            "jsonrpc" => "2.0",
            "method" => $function_name,
            "params" => $parameters,
            "id" => 1
        ]);

        $result = $this->send($request_body);
        $response = json_decode($result, true);
        if ($response['id'] != 1) {
            throw new Exception("incorrect response ID (expected: 1, actual: " . $response['id'] . ")");
        }

        if (isset($response['error'])) {
            throw new Exception("server returned error: " . print_r($response, true));
        }

        return $response['result'];
    }

    private function send($request_body)
    {
        $result = socket_write($this->socket, $request_body . "\n", strlen($request_body) + 1);
        if ($result === false) {
            throw new Exception("unable to send request: " . socket_strerror(socket_last_error()));
        }

        $response = "";
        do {
            $buffer = socket_read($this->socket, 1024);
            $response .= $buffer;
            if (strlen($buffer) < 1024) {
                break;
            }
        } while(true);

        return $response;
    }
}

Dans le code ci-dessus, la méthode connect() crée un socket et utilise socket_connect() pour se connecter au serveur RPC. La méthode call() enverra des informations de demande au format JSON, et la méthode send() enverra les informations de demande au serveur et renverra le résultat de la réponse du serveur.

Lors de la création de l'objet RpcClient, vous devez transmettre l'adresse et le port sur lesquels le serveur écoute ainsi que le délai d'attente d'attente d'une connexion.

  1. PHP implémente un serveur RPC simple

L'implémentation du protocole RPC sur le serveur nécessite les étapes suivantes :

  • Créer un socket d'écoute.
  • Utilisez la fonction socket_bind() pour lier le socket à une adresse IP et un numéro de port spécifiques.
  • Utilisez la fonction socket_listen() pour écouter le socket.
  • Utilisez la fonction socket_accept() pour accepter une demande de connexion client et renvoyer un nouveau socket.
  • Analysez les informations de demande du client et exécutez la fonction correspondante.
  • Envoyer les informations de réponse au client.

Voici un exemple de serveur RPC simple :

class RpcServer
{
    private $url;
    private $port;
    private $timeout;
    private $socket;

    public function __construct($url, $port, $timeout = 30)
    {
        $this->url = $url;
        $this->port = $port;
        $this->timeout = $timeout;
        $this->listen();
    }

    private function listen()
    {
        $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
        if ($this->socket === false) {
            throw new Exception("unable to create socket: " . socket_strerror(socket_last_error()));
        }

        $result = socket_bind($this->socket, $this->url, $this->port);
        if ($result === false) {
            throw new Exception("unable to bind socket to $this->url:$this->port: " . socket_strerror(socket_last_error()));
        }

        $result = socket_listen($this->socket, 5);
        if ($result === false) {
            throw new Exception("unable to listen on socket: " . socket_strerror(socket_last_error()));
        }

        while (true) {
            $client = socket_accept($this->socket);
            $request_string = socket_read($client, 1024);
            $response_string = $this->handle_request($request_string);
            socket_write($client, $response_string, strlen($response_string));
            socket_close($client);
        }
    }

    private function handle_request($request_string)
    {
        $request = json_decode($request_string, true);
        $method = $request['method'];
        $params = $request['params'];

        if (!function_exists($method)) {
            return json_encode([
                "jsonrpc" => "2.0",
                "id" => $request['id'],
                "error" => [
                    "code" => -32601,
                    "message" => "Method not found"
                ]
            ]);
        }

        $result = call_user_func_array($method, $params);

        return json_encode([
            "jsonrpc" => "2.0",
            "id" => $request['id'],
            "result" => $result
        ]);
    }
}

Dans le code ci-dessus, la méthode Listen() crée un socket et utilise socket_bind() pour se lier à l'adresse IP et au port spécifiés. Ensuite, socket_listen() est appelé pour écouter sur le socket, accepter la demande de connexion client et utiliser la fonction socket_accept() pour renvoyer un nouveau socket pour la communication.

Ensuite, le serveur analysera les informations de demande du client et déterminera si la méthode demandée par le client existe. Si elle n'existe pas, il renverra un code d'erreur. Si la méthode existe, le serveur exécutera la fonction correspondante et enverra le résultat au client.

Lors de la création d'un objet RpcServer, vous devez transmettre l'adresse et le port sur lesquels le serveur écoute ainsi que le délai d'attente d'attente d'une connexion.

  1. Résumé

Dans cet article, nous avons appris comment implémenter une application RPC simple en utilisant PHP et communiquer en utilisant le protocole JSON-RPC. Grâce à l'étude de cet article, nous comprenons les principes de base du protocole RPC, comprenons l'utilisation de base de la programmation socket et maîtrisons les méthodes d'analyse et de sérialisation JSON de PHP. Nous pouvons étudier plus en profondeur le protocole RPC et les scénarios d'application associés.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn