ホームページ >バックエンド開発 >PHPの問題 >PHP を使用して単純な RPC クライアントを実装する方法

PHP を使用して単純な RPC クライアントを実装する方法

PHPz
PHPzオリジナル
2023-04-24 14:53:00803ブラウズ

RPC (リモート プロシージャ コール) は、プログラムが別の空間またはマシンにあるサブプログラムを呼び出すことを可能にするコンピュータ通信プロトコルです。このプロトコルを使用すると、RPC プロトコルのクライアントとサーバーを実装する必要がある場合に限り、ローカル関数を呼び出すのと同じようにリモート サービスの関数を呼び出すことができます。

この記事では、PHP を使用して単純な RPC を実装する方法を紹介します。軽量でシンプルなプロトコルである JSON-RPC プロトコルを使用します。

  1. 準備

コードを書き始める前に、次のことを理解する必要があります。

  • JSON-RPC プロトコルとは何ですか。特徴は何ですか?
  • PHP ソケット プログラミング、特にソケット ソケットの使用。
  • PHP の JSON 解析とシリアル化。
  1. PHP は単純な RPC クライアントを実装します

PHP を使用して、リクエストの送信と応答の受信を担当する単純な RPC クライアントを実装できます。そのワークフローは次のとおりです。

  • ソケットソケットを作成します。
  • socket_create() 関数を使用してソケットを作成します。
  • socket_connect() 関数を使用してサーバーに接続します。
  • リクエスト情報をサーバーに送信します。
  • socket_read() 関数を使用して、サーバーから返された結果を読み取ります。

以下は実装例です:

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;
    }
}

上記のコードでは、connect() メソッドはソケットを作成し、socket_connect() を使用して RPC サーバーに接続します。 call()メソッドはリクエスト情報をJSON形式で送信し、send()メソッドはリクエスト情報をサーバーに送信してサーバーの応答結果を返します。

RpcClient オブジェクトを作成するときは、サーバーがリッスンするアドレスとポート、および接続を待機するタイムアウト期間を渡す必要があります。

  1. PHP は単純な RPC サーバーを実装します

サーバーに RPC プロトコルを実装するには、次の手順が必要です。

  • リスニング ソケットソケットを作成する。
  • socket_bind() 関数を使用して、ソケットを特定の IP アドレスとポート番号にバインドします。
  • socket_listen() 関数を使用して、ソケットソケットをリッスンします。
  • socket_accept() 関数を使用して、クライアント接続要求を受け入れ、新しいソケットを返します。
  • クライアントのリクエスト情報を解析し、対応する関数を実行します。
  • 応答情報をクライアントに送信します。

次に、単純な RPC サーバーの例を示します。

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
        ]);
    }
}

上記のコードでは、listen() メソッドがソケットを作成し、socket_bind() を使用して指定されたソケットにバインドします。 IP アドレスとポート。次に、socket_listen() が呼び出されてソケットをリッスンし、クライアント接続要求を受け入れ、socket_accept() 関数を使用して通信用の新しいソケットを返します。

次に、サーバーはクライアントのリクエスト情報を解析し、クライアントがリクエストしたメソッドが存在するかどうかを判断し、存在しない場合はエラーコードを返します。メソッドが存在する場合、サーバーは対応する関数を実行し、結果をクライアントに送信します。

RpcServer オブジェクトを作成するときは、サーバーがリッスンするアドレスとポート、および接続を待機するタイムアウト期間を渡す必要があります。

  1. 概要

この記事では、PHP を使用して単純な RPC アプリケーションを実装し、JSON-RPC プロトコルを使用して通信する方法を学びました。この記事の学習を通じて、RPC プロトコルの基本原理を理解し、ソケット プログラミングの基本的な使用法を理解し、PHP の JSON 解析およびシリアル化方法をマスターし、RPC プロトコルと関連するアプリケーション シナリオをさらに詳しく学習できます。

以上がPHP を使用して単純な RPC クライアントを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。