前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Rpc的实现原理以及实现一个简单的Rpc

Rpc的实现原理以及实现一个简单的Rpc

作者头像
仙士可
发布2019-12-19 14:56:36
1.4K0
发布2019-12-19 14:56:36
举报
文章被收录于专栏:仙士可博客

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

在一个完整的Rpc协议中,包含了以下对象:

1:服务端,提供Rpc服务接口的服务端,可以有多个

2:客户端,请求Rpc服务端,可以有多个

同时,客户端也可以是服务端,服务端也可以是客户端,互相调用不同的服务

Rpc服务启动过程如下:

Rpc服务调用过程如下:

通过这2张图,可能你会发现:

这不就是相当于接口方法调用吗??

可以这么说,Rpc就是一种远程的接口方法调用的协议,

而且是一种跨服务器,跨平台化的通用接口调用的协议,

通过Rpc协议,我们将使用特定的字符串格式,请求其他服务器上的"方法"

同时,我们的客户端也可以不用关心服务端的服务实现了什么,我们只需要注册服务,用户通过字符串请求,就能请求到正确的服务端

服务发现

在Rpc服务启动流程图中,你可能发现了:客户端必须知道有serviceA这个服务,才能进行注册这个服务节点,才能进行调用?

在一般情况下的确是这样的,但是,我们可以做一个服务发现:

服务发现是指当服务端提供某个服务后,并不需要客户端进行注册,直接让服务端通知给客户端自己有这个服务

例如:

小明在服务端A中编写了"登录"服务,

小红在服务端B中编写了"注册"服务

而这2个服务在客户端是未知的,

在这个情况,小明让服务器A 使用udp协议,告诉了客户端以下内容:

新增"登录"服务,在服务器A,ip地址x.x.x.x,调用服务名为:"login"

新增"注册"服务,在服务器B,ip地址x.x.x.x,调用服务名为:"register"

这样的话,客户端接收到数据包,自动新增2个服务

小明则可以请求客户端,构造请求"login",客户端接收到,直接去请求服务器A获取数据

使用php实现一个简单的rpc

服务端代码:

代码语言:javascript
复制
<?php
/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 18-10-21
 * Time: 下午7:33
 */

class RpcServer
{
    protected $tcp_server;
    public function __construct($ip,$port)
    {
        //创建一个tcp服务,用于监听客户端数据
        //创建一个tcp socket服务
        $errno='';
        $errstr='';
        $this->tcp_server = stream_socket_server("tcp://{$ip}:{$port}", $errno, $errstr);
        if (!$this->tcp_server) {
            exit("{$errno} : {$errstr} \n");
        }
        echo "服务创建成功\n";
        while (true) {
            $client = stream_socket_accept($this->tcp_server);
            if ($client) {
                echo "客户端连接成功\n";
                //这里为了简单,我们一次性读取
                $buf = fread($client, 2048);
                echo "客户端请求数据为:{$buf}\n";
                //可以增加客户端数据包验证,ip验证等
                $data = json_decode($buf,1);
                //自行定义数据包格式,这里是用json
                //这儿需要验证json
                $class_name = $data['service'];
                $action_name = $data['action'];
                $parameter = $data['args'];
                //这里需要验证文件,类,方法是否存在
                include_once $class_name.".php";
                $class = new $class_name();
                $rev = $class->$action_name($parameter);
                echo "调用结果:{$rev}\n";
                //发送调用结果给客户端
                fwrite($client, $rev);
                //关闭客户端
                fclose($client);
            }
        }
    }
    public function __destruct() {
        fclose($this->tcp_server);
    }

}

客户端以及客户端请求代码:

代码语言:javascript
复制
<?php
/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 18-10-21
 * Time: 下午7:43
 */

//服务节点注册(直接模拟注册过程)
$service = [
    'Login' => [
        [
            'node' => 'node1',
            'ip'   => '127.0.0.1',
            'port' => '9501',
        ],
        [
            'node' => 'node2',
            'ip'   => '127.0.0.1',
            'port' => '9601',
        ],
    ]
];


//直接调用客户端请求服务端
$arr = [
    'service' => 'Login',
    'action'  => 'userLogin',
    'args'    => [
        'name'     => 'tioncico',
        'password' => '123456'
    ]
];
//根据请求服务名,获得服务节点(一个服务可以被多个服务器注册)
$node_array = $service[$arr['service']];
$node =$node_array[array_rand($node_array)];
echo "请求的服务节点为:{$node['node']}\n";
$fp = stream_socket_client("tcp://{$node['ip']}:{$node['port']}");

$sendStr = json_encode($arr);

fwrite($fp, $sendStr);
$data = fread($fp, 65533);

echo "服务端返回结果:{$data}\n";

启动服务端代码:

代码语言:javascript
复制
<?php
/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 18-10-21
 * Time: 下午7:37
 */

include "RpcServer.php";
$server = new RpcServer('0.0.0.0',9501);
代码语言:javascript
复制
<?php
/**
 * Created by PhpStorm.
 * User: tioncico
 * Date: 18-10-21
 * Time: 下午7:37
 */

include "RpcServer.php";
$server = new RpcServer('0.0.0.0',9601);

调用结果:

EasySwoole Rpc组件

直接使用EasySwoole 3.x版本的Rpc组件,可实现一个功能完善的Rpc框架

https://github.com/easy-swoole/rpc

本文为仙士可原创文章,转载无需和我联系,但请注明来自仙士可博客www.php20.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/10/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Rpc服务启动过程如下:
  • Rpc服务调用过程如下:
  • 服务发现
  • 使用php实现一个简单的rpc
  • EasySwoole Rpc组件
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档