> 백엔드 개발 > PHP 튜토리얼 > PHP RPC를 구현하는 방법은 무엇입니까?

PHP RPC를 구현하는 방법은 무엇입니까?

藏色散人
풀어 주다: 2023-04-06 17:58:01
원래의
3336명이 탐색했습니다.

PHP RPC를 구현하는 방법은 무엇입니까?

1. rpc

RPC란 Remote Procedure Call의 약어로 "원격 절차 호출"을 의미합니다. 현재 주류 플랫폼은 분산 시스템 아키텍처에서 서로 다른 시스템 간의 원격 통신 및 상호 호출 요구를 충족하기 위해 다양한 원격 호출 기술을 지원합니다. 원격 호출의 적용 시나리오는 매우 광범위하며 구현 방법도 다양합니다.

2 통신 프로토콜 수준에서

HTTP 프로토콜 기반(예: 텍스트 기반 SOAP(XML), Rest(JSON), 바이너리 Hessian(Binary) 기반)
TCP 프로토콜 기반(일반적으로 Mina, Netty 및 기타 고성능 네트워크 프레임워크의 도움)

3. 다양한 개발 언어 및 플랫폼 수준에서

단일 언어 또는 플랫폼별 지원 통신 기술(예: Java 플랫폼 RMI, .NET 플랫폼) Remoting)
교차 플랫폼 통신 기술 지원(예: HTTP Rest, Thrift 등)

4. 호출 프로세스 관점에서

동기 통신 호출(동기 RPC)
비동기 통신 호출(MQ, 비동기 RPC)

5. 몇 가지 일반적인 통신 유형 방법

원격 데이터 공유(예: 서로 다른 시스템 간의 통신을 위해 원격 파일, 공유 데이터베이스 등 공유)
메시지 대기열
RPC(원격 프로시저 호출)

6.php는 간단한 rpc

디렉터리 구조를 구현합니다

PHP RPC를 구현하는 방법은 무엇입니까?

rpc 서버

<?php/**
 * User: yuzhao
 * CreateTime: 2018/11/15 下午11:46
 * Description: Rpc服务端
 */class RpcServer {    /**
     * User: yuzhao
     * CreateTime: 2018/11/15 下午11:51
     * @var array
     * Description: 此类的基本配置
     */
    private $params = [        &#39;host&#39;  => &#39;&#39;,  // ip地址,列出来的目的是为了友好看出来此变量中存储的信息
        &#39;port&#39;  => &#39;&#39;, // 端口
        &#39;path&#39;  => &#39;&#39; // 服务目录
    ];    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:14
     * @var array
     * Description: 本类常用配置
     */
    private $config = [        &#39;real_path&#39; => &#39;&#39;,        &#39;max_size&#39;  => 2048 // 最大接收数据大小
    ];    /**
     * User: yuzhao
     * CreateTime: 2018/11/15 下午11:50
     * @var nul
     * Description:
     */
    private $server = null;    /**
     * Rpc constructor.
     */
    public function __construct($params)
    {        $this->check();        $this->init($params);
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:0
     * Description: 必要验证
     */
    private function check() {        $this->serverPath();
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/15 下午11:48
     * Description: 初始化必要参数
     */
    private function init($params) {        // 将传递过来的参数初始化
        $this->params = $params;        // 创建tcpsocket服务
        $this->createServer();
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:0
     * Description: 创建tcpsocket服务

     */
    private function createServer() {        $this->server = stream_socket_server("tcp://{$this->params[&#39;host&#39;]}:{$this->params[&#39;port&#39;]}", $errno,$errstr);        if (!$this->server) exit([
            $errno,$errstr
        ]);
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/15 下午11:57
     * Description: rpc服务目录
     */
    public function serverPath() {
        $path = $this->params[&#39;path&#39;];
        $realPath = realpath(__DIR__ . $path);        if ($realPath === false ||!file_exists($realPath)) {            exit("{$path} error!");
        }        $this->config[&#39;real_path&#39;] = $realPath;
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/15 下午11:51
     * Description: 返回当前对象
     */
    public static function instance($params) {        return new RpcServer($params);
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:06
     * Description: 运行
     */
    public function run() {        while (true) {
            $client = stream_socket_accept($this->server);            if ($client) {                echo "有新连接\n";
                $buf = fread($client, $this->config[&#39;max_size&#39;]);
                print_r(&#39;接收到的原始数据:&#39;.$buf."\n");                // 自定义协议目的是拿到类方法和参数(可改成自己定义的)
                $this->parseProtocol($buf,$class, $method,$params);                // 执行方法
                $this->execMethod($client, $class, $method, $params);                //关闭客户端
                fclose($client);                echo "关闭了连接\n";
            }
        }
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:19
     * @param $class
     * @param $method
     * @param $params
     * Description: 执行方法
     */
    private function execMethod($client, $class, $method, $params) {        if($class && $method) {            // 首字母转为大写
            $class = ucfirst($class);
            $file = $this->params[&#39;path&#39;] . &#39;/&#39; . $class . &#39;.php&#39;;            //判断文件是否存在,如果有,则引入文件
            if(file_exists($file)) {                require_once $file;                //实例化类,并调用客户端指定的方法
                $obj = new $class();                //如果有参数,则传入指定参数
                if(!$params) {
                    $data = $obj->$method();
                } else {
                    $data = $obj->$method($params);
                }                // 打包数据
                $this->packProtocol($data);                //把运行后的结果返回给客户端
                fwrite($client, $data);
            }
        } else {
            fwrite($client, &#39;class or method error&#39;);
        }
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:10
     * Description: 解析协议
     */
    private function parseProtocol($buf, &$class, &$method, &$params) {
        $buf = json_decode($buf, true);
        $class = $buf[&#39;class&#39;];
        $method = $buf[&#39;method&#39;];
        $params = $buf[&#39;params&#39;];
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:30
     * @param $data
     * Description: 打包协议
     */
    private function packProtocol(&$data) {
        $data = json_encode($data, JSON_UNESCAPED_UNICODE);
    }

}

RpcServer::instance([    &#39;host&#39;  => &#39;127.0.0.1&#39;,    &#39;port&#39;  => 8888,    &#39;path&#39;  => &#39;./api&#39;])->run();
로그인 후 복사

rpc 클라이언트

<?php/**
 * User: yuzhao
 * CreateTime: 2018/11/16 上午12:2
 * Description: Rpc客户端
 */class RpcClient {    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:21
     * @var array
     * Description: 调用的地址
     */
    private $urlInfo = array();    /**
     * RpcClient constructor.
     */
    public function __construct($url)
    {        $this->urlInfo = parse_url($url);
    }    /**
     * User: yuzhao
     * CreateTime: 2018/11/16 上午12:2
     * Description: 返回当前对象
     */
    public static function instance($url) {        return new RpcClient($url);
    }    public function __call($name, $arguments)
    {        // TODO: Implement __call() method.
        //创建一个客户端
        $client = stream_socket_client("tcp://{$this->urlInfo[&#39;host&#39;]}:{$this->urlInfo[&#39;port&#39;]}", $errno, $errstr);        if (!$client) {            exit("{$errno} : {$errstr} \n");
        }
        $data = [            &#39;class&#39;  => basename($this->urlInfo[&#39;path&#39;]),            &#39;method&#39; => $name,            &#39;params&#39; => $arguments
        ];        //向服务端发送我们自定义的协议数据
        fwrite($client, json_encode($data));        //读取服务端传来的数据
        $data = fread($client, 2048);        //关闭客户端
        fclose($client);        return $data;
    }
}
$cli = new RpcClient(&#39;http://127.0.0.1:8888/test&#39;);echo $cli->tuzisir1()."\n";echo $cli->tuzisir2(array(&#39;name&#39; => &#39;tuzisir&#39;, &#39;age&#39; => 23));
로그인 후 복사

서비스에서 제공하는 파일

<?php/**
 * User: yuzhao
 * CreateTime: 2018/11/16 上午12:28
 * Description:
 */class Test {    public function tuzisir1() {        return &#39;我是无参方法&#39;;
    }    public function tuzisir2($params) {        return $params;
    }
}
로그인 후 복사

Effect

PHP RPC를 구현하는 방법은 무엇입니까?

7. RPC

성능: RPC 성능에 영향을 미치는 여러 측면이 있습니다.
1. 직렬화/역직렬화 프레임워크
2. 네트워크 프로토콜, 네트워크 모델, 스레드 모델 등

보안
RPC 보안은 주로 인증 및 액세스에 있습니다. 서비스 인터페이스의 지원을 제어합니다.

크로스 플랫폼
다양한 운영 체제, 다양한 프로그래밍 언어 및 플랫폼에 걸쳐 있습니다.

위 내용은 PHP RPC를 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿