使用PHP来简单的创建一个RPC服务
Posted liliuguang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用PHP来简单的创建一个RPC服务相关的知识,希望对你有一定的参考价值。
RPC全称为Remote Procedure Call,翻译过来为"远程过程调用"。主要应用于不同的系统之间的远程通信和相互调用。
比如有两个系统,一个是php写的,一个是JAVA写的,而PHP想要调用JAVA中的某个类的某个方法,这时候就需要用到RPC了。
怎么调?直接调是不可能,只能是PHP通过某种自定义协议请求JAVA的服务,JAVA解析该协议,在本地实例化类并调用方法,然后把结果返回给PHP。
这里我们用PHP的socket扩展来创建一个服务端和客户端,演示调用过程。
RpcServer.php代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
<?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( ‘/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‘ ; //判断文件是否存在,如果有,则引入文件 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 , ‘class or method error‘ );
//关闭客户端 fclose( $client );
public function __destruct() fclose( $this ->serv);
new RpcServer( ‘127.0.0.1‘ , 8888, ‘./service‘ ); |
RpcClient.php代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<?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[‘host‘]:$this->urlInfo[‘port‘]" , $errno , $errstr ); if (! $client ) exit ( "$errno : $errstr \\n" );
//传递调用的类名 $class = basename ( $this ->urlInfo[ ‘path‘ ]); $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( ‘http://127.0.0.1:8888/test‘ ); echo $cli ->hehe(); echo $cli ->hehe2( array ( ‘name‘ => ‘test‘ , ‘age‘ => 27)); |
然后分别运行上面两个脚本(注意,php要添加环境变量)
1
2
|
> php RpcServer.php > php RpcClient.php |
结果如下:
Test.php代码如下:
1
2
3
4
5
6
7
8
9
|
<?php class Test public function hehe() return ‘hehe‘ ;
public function hehe2( $params ) return json_encode( $params );
|
目录结构如下:
上面我们自定义的协议,可以随意修改,只要是客户端和服务端两边能够统一并能解析。
客户端通过请求服务端,把要调用的类,方法和参数传递给服务端,服务端去通过实例化调用方法返回结果。
以上是关于使用PHP来简单的创建一个RPC服务的主要内容,如果未能解决你的问题,请参考以下文章
Trac JSON RPC 问题 - 将 jQuery AJAX 与 PHP 代理一起使用