RpcServer.php
<?php
/**
* Created by PhpStorm.
* User: songyongzhan
* Date: 2018/11/8
* Time: 17:28
* Email: songyongzhan@qianbao.com
*/
class RpcServer {
protected $server = NULL;
public function __construct($host, $port, $path) {
$this->server = stream_socket_server(sprintf("tcp://%s:%s", $host, $port), $errno, $error);
if (!$this->server) {
exit("{$errno}:{$error}");
}
$realPath = realpath(__DIR__ . DIRECTORY_SEPARATOR . $path);
if ($realPath === FALSE || !file_exists($realPath)) {
exit("{$realPath} error.\n");
}
while (TRUE) {
$client = @stream_socket_accept($this->server);
if ($client) {
//这里为了简单,我们一次性读取
$buf = fread($client, 2048);
//解析客户端发送过来的协议
$classRet = preg_match('/Rpc-Class:\s(.*);[\r\n|\r|\n]?/i', $buf, $class);
$methodRet = preg_match('/Rpc-Method:\s(.*);[\r\n|\r|\n]?/i', $buf, $method);
$paramsRet = preg_match('/Rpc-Params:\s(.*);[\r\n|\r|\n]?/i', $buf, $params);
printf("===================================\n");
printf("classRet:%s methodRet:%s $paramsRet:%s class:%s\n", $classRet, $methodRet,$paramsRet, json_encode($class));
printf("===================================\n");
if ($classRet && $methodRet) {
$class = ucfirst($class[1]);
$file = $realPath . '/' . $class . '.php';
//判断文件是否存在,如果有,则引入文件
if (file_exists($file)) {
require_once $file;
//实例化类,并调用客户端指定的方法
$obj = new $class();
//如果有参数,则传入指定参数
if (!$paramsRet) {
$data = call_user_func_array([$obj,$method[1]],[]);
} else {
$data = call_user_func_array([$obj,$method[1]],json_decode($params[1]));
}
//把运行后的结果返回给客户端
fwrite($client, $data);
}
} else {
fwrite($client, "class or method error\n");
}
//关闭客户端
fclose($client);
}
}
}
public function __destruct() {
fclose($this->server);
}
}
new RpcServer('127.0.0.1', 8888, 'static');RpcClient.php
<?php
/**
* Created by PhpStorm.
* User: songyongzhan
* Date: 2018/11/8
* Time: 17:36
* Email: songyongzhan@qianbao.com
*/
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;
//printf($proto);
//向服务端发送我们自定义的协议数据
fwrite($client, $proto);
//读取服务端传来的数据
$data = fread($client, 2048);
//关闭客户端
fclose($client);
return $data;
}
}
$cli = new RpcClient('http://127.0.0.1:8888/test');
//echo $cli->hehe(['name'=>'james'],'13');
echo $cli->hehe('james','13')."\n";
echo $cli->hehe2(array('name' => 'test', 'age' => 27))."\n";static/Test.php
<?php
/**
* Created by PhpStorm.
* User: songyongzhan
* Date: 2018/11/8
* Time: 17:43
* Email: songyongzhan@qianbao.com
*/
class Test {
public function hehe($name, $age) {
return sprintf('hello %s age:%d', $name, $age);
}
public function hehe2($params) {
return json_encode($params);
}
}启动方式:
1、php RpcServer.php
2、php RpcClient.php
服务器端:

客户端

整体的目录架构是:

请访问这个地址查看:
http://www.cnblogs.com/jkko123/p/6574808.html