Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Menganalisis cara PHP boleh membuat perkhidmatan RPC dengan cepat (pertunjukan kod)

Menganalisis cara PHP boleh membuat perkhidmatan RPC dengan cepat (pertunjukan kod)

藏色散人
藏色散人ke hadapan
2022-11-09 16:18:143201semak imbas

Artikel ini akan memperkenalkan kepada anda apa itu RPC dan cara menggunakan PHP untuk membuat perkhidmatan RPC secara ringkas dan cepat, sebenarnya sangat mudah, mari kita lihat~ Semoga ia dapat membantu rakan-rakan yang memerlukan~

Menganalisis cara PHP boleh membuat perkhidmatan RPC dengan cepat (pertunjukan kod)

RPC ialah singkatan kepada Remote Procedure Call, yang diterjemahkan kepada "panggilan prosedur jauh". Terutamanya digunakan untuk komunikasi jauh dan panggilan bersama antara sistem yang berbeza. [Pembelajaran yang disyorkan:

Tutorial video PHP]

Sebagai contoh, terdapat dua sistem, satu ditulis dalam PHP dan satu lagi ditulis dalam JAVA, dan PHP mahu memanggil kelas tertentu dalam JAVA Untuk kaedah tertentu, RPC perlu digunakan pada masa ini.

Bagaimana untuk menyesuaikan diri? Pelarasan langsung adalah mustahil. PHP hanya boleh meminta perkhidmatan JAVA melalui beberapa protokol tersuai JAVA menghuraikan protokol, membuat instantiate kelas secara setempat dan memanggil kaedah, dan kemudian mengembalikan hasilnya kepada PHP.

Di sini kami menggunakan sambungan soket PHP untuk mencipta pelayan dan klien untuk menunjukkan proses panggilan.

Kod RpcServer.php adalah seperti berikut:

<?php
class RpcServer {
    protected $serv = null;
 
    public function __construct($host, $port, $path) {
        //创建一个tcp socket服务
        $this->serv = stream_socket_server("tcp://{$host}:{$port}", $errno, $errstr);
        if (!$this->serv) {
            exit("{$errno} : {$errstr} \n");
        }
        //判断我们的RPC服务目录是否存在
        $realPath = realpath(__DIR__ . $path);
        if ($realPath === false || !file_exists($realPath)) {
            exit("{$path} error \n");
        }
 
        while (true) {
            $client = stream_socket_accept($this->serv);
 
            if ($client) {
                //这里为了简单,我们一次性读取
                $buf = fread($client, 2048);
                //解析客户端发送过来的协议
                $classRet = preg_match(&#39;/Rpc-Class:\s(.*);\r\n/i&#39;, $buf, $class);
                $methodRet = preg_match(&#39;/Rpc-Method:\s(.*);\r\n/i&#39;, $buf, $method);
                $paramsRet = preg_match(&#39;/Rpc-Params:\s(.*);\r\n/i&#39;, $buf, $params);
                 
                if($classRet && $methodRet) {
                    $class = ucfirst($class[1]);
                    $file = $realPath . &#39;/&#39; . $class . &#39;.php&#39;;
                    //判断文件是否存在,如果有,则引入文件
                    if(file_exists($file)) {
                        require_once $file;
                        //实例化类,并调用客户端指定的方法
                        $obj = new $class();
                        //如果有参数,则传入指定参数
                        if(!$paramsRet) {
                            $data = $obj->$method[1]();
                        } else {
                            $data = $obj->$method[1](json_decode($params[1], true));
                        }
                        //把运行后的结果返回给客户端
                        fwrite($client, $data);
                    }
                } else {
                    fwrite($client, &#39;class or method error&#39;);
                }
                //关闭客户端
                fclose($client);
            }
        }
    }
 
    public function __destruct() {
        fclose($this->serv);
    }
}
 
new RpcServer(&#39;127.0.0.1&#39;, 8888, &#39;./service&#39;);
Kod RpcClient.php adalah seperti berikut:

<?php
 
class RpcClient {
    protected $urlInfo = array();
     
    public function __construct($url) {
        //解析URL
        $this->urlInfo = parse_url($url);
        if(!$this->urlInfo) {
            exit("{$url} error \n");
        }
    }
     
    public function __call($method, $params) {
        //创建一个客户端
        $client = stream_socket_client("tcp://{$this->urlInfo[&#39;host&#39;]}:{$this->urlInfo[&#39;port&#39;]}", $errno, $errstr);
        if (!$client) {
            exit("{$errno} : {$errstr} \n");
        }
        //传递调用的类名
        $class = basename($this->urlInfo[&#39;path&#39;]);
        $proto = "Rpc-Class: {$class};" . PHP_EOL;
        //传递调用的方法名
        $proto .= "Rpc-Method: {$method};" . PHP_EOL;
        //传递方法的参数
        $params = json_encode($params);
        $proto .= "Rpc-Params: {$params};" . PHP_EOL;
        //向服务端发送我们自定义的协议数据
        fwrite($client, $proto);
        //读取服务端传来的数据
        $data = fread($client, 2048);
        //关闭客户端
        fclose($client);
        return $data;
    }
}
 
$cli = new RpcClient(&#39;http://127.0.0.1:8888/test&#39;);
echo $cli->hehe();
echo $cli->hehe2(array(&#39;name&#39; => &#39;test&#39;, &#39;age&#39; => 27));
Kemudian jalankan dua skrip di atas masing-masing (perhatikan bahawa php perlu menambah Pembolehubah persekitaran)

> php RpcServer.php
> php RpcClient.php
Hasilnya adalah seperti berikut:

Ujian.php kod adalah seperti berikut:

<?php
class Test {
 public function hehe() {
 return &#39;hehe&#39;;
 }
 public function hehe2($params) {
 return json_encode($params);
 }
}
Struktur direktori adalah seperti berikut:

Protokol tersuai kami di atas boleh diubah suai sesuka hati, selagi klien dan pelayan boleh disatukan dan dihuraikan.

Pelanggan melepasi kelas, kaedah dan parameter untuk dipanggil ke pelayan dengan meminta pelayan dan pelayan mengembalikan hasilnya dengan membuat kaedah panggilan.

Atas ialah kandungan terperinci Menganalisis cara PHP boleh membuat perkhidmatan RPC dengan cepat (pertunjukan kod). Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:juejin.im. Jika ada pelanggaran, sila hubungi admin@php.cn Padam