thinkphp6 swoole-rpc 基于thinkphp6(tp6)+ swoole的rpc框架实现

本文介绍了如何基于ThinkPHP6和Swoole构建一个RPC框架,详细阐述了从本地调用到远程调用的实现过程,包括原理、序列化、反射调用等关键步骤,并提供了相应的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

浏览了大量关于php 的rpc,但是多数为原生php实现rpc的demo。虽然很多人都知道rpc 的原理,但是对于编写代码并没有一个直观的感受,所以这次手写一个自定义rpc框架,基于使用tp6来完成rpc框架。这次以代码为主,中间使用的一些技术分享,理论性的东西不在一一概括,用最简单的话来解释其中很多技术!(如果对rpc不太了解的话,请翻上一篇文章)

概括

简述:client端调用server端 如果server端的代码为本地则是本地调用,如果server端的代码在另外一台机器就需要远程调用(Rpc协议)

本地调用(伪代码)

<?php
    
    #如果代码在本地(同一台机器,同一个项目中) 我们就可以通过new(实例化)的方式来进行调用
    class Client 
	{
         public function A()
         {
             return (new Server())->B();
         }
	}

	class Server 
    {
        public function B(){
            return '我是服务端,代码在本地';
        }
    }

远程调用

假设:client端 在 ip 192.168.1.2的机器上

server端 在 ip 192.168.1.3的机器上

如果我们还是想通过new这种方式去进行调用的话,那么就需要远程调用

远程调用伪代码

#client ip 192.168.1.2

<?php
    
    class Client {
         public function A()
         {	
             #最终我们要完成的也是实例化RpcClient去调用Server服务的B方法
             return (new RpcClient())->Service('Server')->B(); 
         }
	}



#server ip 192.168.1.3
<?php
    class Server 
    {
        public function B()
        {
            return '我是服务端,代码在远程';
        }
    }

RpcClient即为Rpc框架的客户端

原理

下图为我们要完成的框架需要做的步骤,以及远程调用的步骤(根据序号):

在client端发起一个远程伪代码中(new RpcClient())->Service('Server')->B();

  1. 通过实例化框架RpcClient将发起代理服务

  2. 将Server和B方法,以及B方法可能带有的参数序列化

  3. 通过swoole把序列化的消息发送给服务端

  4. 服务端接收消息并反序列化

  5. 通过反射调用调用服务端的Server类下的B方法

  6. 服务端Server类B方法返回的结果序列化

  7. 将返回的序列化结果通过swoole发送给客户端

  8. 客户端通过反序列化得到结果

在上述的过程中省略了服务注册。保留了最真实的序列化和通信过程。

所以们要完成的功能就是

通信、序列化、调用这三个最主要的逻辑,接下来我们一一实现。

准备阶段

  1. php版本>= 7.4、安装swoole拓展(php 7.4 默认安装4.4以上版本的拓展)

  2. 需要安装composer

  3. 准备两个tp6项目分别命名为tp6-clienttp6-server

  4. 需要开通9008端口(端口自定义,本使用的是9008)

  5. 可以通过http也可以访问到

目标

  1. 实现swoole通信

  2. 序列化和反序列化

  3. 反射调用并返回结果

目录结构

/tianyu                         (自定义目录名)
├── src                             
│    ├── command                  (自定义命令)
│    │	└── Server.php           (根据tp6命令行自行创建的命令启动文件,启动swoole)
│    ├── common
│    │	├── Buffer.php            缓冲器
│    │	├── Packer.php            定义包头
│    │	├── Paser.php             解析协议
│    │	└── Protocol.php          协议封装
│    ├── reflection
│    │   └──Contaoner.php         自定义容器
│    ├── register.php             注册中心文件
│    ├── RpcClient.php            客户端
│    ├── RpcServer.php            服务端   
│    └── Server.php               tp6命令行注册文件          
└── composer.json                 compsoer文件   

一、安装tp6框架

composer create-project topthink/think tp-client

composer create-project top

二、使用composer开发自定义框架,自定义composer.json

为什么使用composer开发?

ThinkPHP6.0遵循PSR-2命名规范和PSR-4自动加载规范,并且注意如下规范:

目录和文件

- 目录使用小写+下划线;
- 类库、函数文件统一以`.php`为后缀;
- 类的文件名均以命名空间定义,并且命名空间的路径和类库文件所在路径一致;
- 类(包含接口和Trait)文件采用驼峰法命名(首字母大写),其它文件采用小写+下划线命名;
- 类名(包括接口和Trait)和文件名保持一致,统一采用驼峰法命名(首字母大写);

函数和类、属性命名

- 类的命名采用驼峰法(首字母大写),例如 `User`、`UserType`;
- 函数的命名使用小写字母和下划线(小写字母开头)的方式,例如 `get_client_ip`;
- 方法的命名使用驼峰法(首字母小写),例如 `getUserName`;
- 属性的命名使用驼峰法(首字母小写),例如 `tableName`、`instance`;
- 特例:以双下划线`__`打头的函数或方法作为魔术方法,例如 `__call` 和 `__autoload`;

composer开发一般情况下使用composer命令,不过这次先使用手动更改目录文件的形式将自定义框架加载到composer中

根据上述开发规范,应该将自定义框架目录放在vendor目录下,在composer.json中配置自己的命名空间

composer.json文件如下:

{
  "name": "tianyu-rpc/tianyu-rpc",
  "description": "description",
  "minimum-stability": "stable",
  "license": "proprietary",
  "authors": [
    {
      "name": "45576",
      "email": "email@example.com"
    }
  ],
  "require": {
    "php": ">=7.4",
    "ext-json": "*",
    "swoole/ide-helper": "^4.3"
  },
  "autoload": {
    "psr-4": {
      "tianyu\\": "src"
    }
  }
}

最重要的是autoloadpsr-4,定义自己的命名空间

然后为了将自己的命名空间加入到composer包管理中还需要如下的几个步骤:

1、在 根目录/vendor/composer目录下找到autoload_psr4.php(注意以下注释内容)

<?php

// autoload_psr4.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'think\\trace\\' => array($vendorDir . '/topthink/think-trace/src'),
    'think\\' => array($vendorDir . '/topthink/think-helper/src', $vendorDir . '/topthink/think-orm/src', $vendorDir . '/topthink/framework/src/think'),
    'app\\' => array($baseDir . '/app'),
    'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
    'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
    'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
    'Symfony\\Component\\VarDumper\\' => array($vendorDir . '/symfony/var-dumper'),
    'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
    'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
    'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
    'Psr\\Cache\\' => array($vendorDir . '/psr/cache/src'),
    'League\\MimeTypeDetection\\' => array($vendorDir . '/league/mime-type-detection/src'),
    'League\\Flysystem\\Cached\\' => array($vendorDir . '/league/flysystem-cached-adapter/src'),
    'League\\Flysystem\\' => array($vendorDir . '/league/flysystem/src'),
    //只需要加入我们自己的命名空间和目录,其余不要无脑复制
    'tianyu\\' => array($vendorDir . '/tianyu/src'),
);

2、在 根目录/vendor/composer目录下找到autoload_static.php(注意以下注释内容)

需要修改两个地方$prefixLengthsPsr4$prefixLengthsPsr4

<?php

// autoload_static.php @generated by Composer

namespace Composer\Autoload;

class ComposerStaticInit6e727dc751020a5cd17c7dc2b4c706c7
{
    public static $files = array (
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前路莫回眸丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值