Use PHP to simply create an RPC service

Time:2021-2-25

The full name of RPC is remote procedure call, which translates as “remote procedure call”. It is mainly used in remote communication and mutual call between different systems.

For example, there are two systems, one is written in PHP and the other is written in Java. If PHP wants to call a method of a class in Java, RPC is needed.

How to adjust it? It’s impossible to call directly. PHP can only request the service of Java through some custom protocol. Java parses the protocol, instantiates the class locally and calls the method, and then returns the result to PHP.

Here we use the socket extension of PHP to create a server and a client to demonstrate the calling process.

RpcServer.php The code is as follows:

serv = stream_socket_server("tcp://{$host}:{$port}", $errno, $errstr);
        if (!$this->serv) {
            exit("{$errno} : {$errstr} \n");
        }
        //Determine whether our RPC service directory exists
        $realPath = realpath(__DIR__ . $path);
        if ($realPath === false || !file_exists($realPath)) {
            exit("{$path} error \n");
        }
 
        while (true) {
            $client = stream_socket_accept($this->serv);
 
            if ($client) {
                //Here, for simplicity, we read it all at once
                $buf = fread($client, 2048);
                //Parsing the protocol sent by the client
                $classRet = preg_match('/Rpc-Class:\s(.*);\r\n/i', $buf, $class);
                $methodRet = preg_match('/Rpc-Method:\s(.*);\r\n/i', $buf, $method);
                $paramsRet = preg_match('/Rpc-Params:\s(.*);\r\n/i', $buf, $params);
                 
                if($classRet && $methodRet) {
                    $class = ucfirst($class[1]);
                    $file = $realPath . '/' . $class . '.php';
                    //Judge whether the file exists, if so, import the file
                    if(file_exists($file)) {
                        require_once $file;
                        //Instantiate the class and call the method specified by the client
                        $obj = new $class();
                        //If there are parameters, the specified parameters are passed in
                        if(!$paramsRet) {
                            $data = $obj->$method[1]();
                        } else {
                            $data = $obj->$method[1](json_decode($params[1], true));
                        }
                        //Return the running result to the client
                        fwrite($client, $data);
                    }
                } else {
                    fwrite($client, 'class or method error');
                }
                //Close client
                fclose($client);
            }
        }
    }
 
    public function __destruct() {
        fclose($this->serv);
    }
}
 
new RpcServer('127.0.0.1', 8888, './service');

RpcClient.php The code is as follows:

urlInfo = parse_url($url);
        if(!$this->urlInfo) {
            exit("{$url} error \n");
        }
    }
     
    public function __call($method, $params) {
        //Create a client
        $client = stream_socket_client("tcp://{$this->urlInfo['host']}:{$this->urlInfo['port']}", $errno, $errstr);
        if (!$client) {
            exit("{$errno} : {$errstr} \n");
        }
        //Pass the class name of the call
        $class = basename($this->urlInfo['path']);
        $proto = "Rpc-Class: {$class};" . PHP_EOL;
        //Pass the method name of the call
        $proto .= "Rpc-Method: {$method};" . PHP_EOL;
        //Pass the parameters of the method
        $params = json_encode($params);
        $proto .= "Rpc-Params: {$params};" . PHP_EOL;
        //Send our custom protocol data to the server
        fwrite($client, $proto);
        //Read the data from the server
        $data = fread($client, 2048);
        //Close client
        fclose($client);
        return $data;
    }
}
 
$cli = new RpcClient('http://127.0.0.1:8888/test');
echo $cli->hehe();
echo $cli->hehe2(array('name' => 'test', 'age' => 27));

Then run the above two scripts separately (note that PHP needs to add environment variables)

> php RpcServer.php
> php RpcClient.php

The results are as follows

Use PHP to simply create an RPC serviceUse PHP to simply create an RPC service

Test.php The code is as follows:

The directory structure is as follows:

Use PHP to simply create an RPC service

The above custom protocol can be modified at will, as long as the client and server can be unified and parsed.

By requesting the server, the client passes the class, method and parameter to be called to the server, and the server returns the result by instantiating the calling method.

 

For those interested in PHP back-end technology and PHP architecture technology, my official group is 1023755567Click here Learn together and discuss with each other.
There is already management in the group to sort out the knowledge system (source code, learning video and other materials). You are welcome to get it for free.

 

 

PHP advanced learning mind map, interview; free access to documents and video resources

Recommended Today

Third party calls wechat payment interface

Step one: preparation 1. Wechat payment interface can only be called if the developer qualification has been authenticated on wechat open platform, so the first thing is to authenticate. It’s very simple, but wechat will charge 300 yuan for audit 2. Set payment directory Login wechat payment merchant platform( pay.weixin.qq . com) — > Product […]