zoukankan      html  css  js  c++  java
  • 基于 Thrift + Laravel RPC 调用实现

    项目初始化

    为此,我们先初始化一个新的 Laravel 应用 thrift

    1

    laravel new thrift

     在 thrift 项目根目录下新增一个 thrift 子目录,然后在该子目录下创建 Thrift IDL 文件 org.thrift,用于定义和用户相关的服务接口(语言为 PHP,命名空间为 AppThriftOrg):

    namespace php App.Thrift.OrgThrift

    service OrgThrift {
    string routeRequest(1:i32 request)
    }

     接着在项目根目录下运行如下命令,根据上述 IDL 文件生成相关的服务代码:

    1

    thrift -r --gen php:server -out ./ thrift/org.thrift

     这样就会在 AppThriftOrgThrift命名空间下生成对应的服务代码:

     

    然后通过 Composer 安装 Thrift PHP 依赖包:

    1

    composer require apache/thrift

    编写服务端代码

     接下来,我们就可以编写服务端代码了,在 app 目录下新建一个 Services/Server 子目录,然后在该目录下创建服务接口类OrgService,该类实现自 AppThriftorgOrgIf 接口:

    在服务接口实现中,我们通过传入参数查询数据库并返回对应的记录,这里为了简化逻辑,我们直接返回,将参数校验、缓存优化、异常处理通通省略。

    接下来,我们来编写服务端启动命令类,在 Laravel 框架中,这可以通过 Artisan 控制台来完成,首先创建命令类:

    1

    php artisan make:command RpcServerStart

      该命令会在 app/Console/Commands 目录下生成 RpcServerStart.php,我们编写 RpcServerStart 命令类代码如下:

    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

    60

    61

    62

    63

    <?php

    namespace AppConsoleCommands;

    use AppServicesServerOrgService;

    use AppThriftOrgThriftOrgThriftProcessor;

    use IlluminateConsoleCommand;

    use ThriftExceptionTException;

    use ThriftFactoryTBinaryProtocolFactory;

    use ThriftFactoryTTransportFactory;

    use ThriftServerTServerSocket;

    use ThriftServerTSimpleServer;

    use ThriftTMultiplexedProcessor;

    class RpcServerStart extends Command

    {

    /**

    * The name and signature of the console command.

    *

    * @var string

    */

    protected $signature = 'rpc:start'`;`

    /**

    * The console command description.

    *

    * @var string

    */

    protected $description = 'Start Thrift RPC Server'`;`

    /**

    * Create a new command instance.

    *

    * @return void

    */

    public function __construct()

    {

    parent::__construct();

    }

    /**

    * Execute the console command.

    *

    * @return mixed

    */

    public function handle()

    {

    try {

    $thriftProcess = new OrgThriftProcessor(`new OrgService());`

    $tFactory = new TTransportFactory();

    $pFactory = new TBinaryProtocolFactory();

    $processor = new TMultiplexedProcessor();

    // 注册服务

    $processor`->registerProcessor('OrgService', $thriftProcess`);

    // 监听本地 8888 端口,等待客户端连接请求

    $transport = new TServerSocket(`'127.0.0.1'`, 8001);

    $server = new TSimpleServer(`$processor,` `$transport, $tFactory,` `$tFactory, $pFactory,` `$pFactory);`

    $this`->info("Server Start [127.0.0.1:8001]!");`

    $server`->serve();`

    } catch (TException $exception`) {`

    $this`->error("服务启动失败!");`

    }

    }

    }

      别忘了在 app/Console/Kernel.php 中注册上述命令类使其生效:

    1

    2

    3

    4

    5

    use AppConsoleCommandsRpcServerStart;

    protected $commands = [

    RpcServerStart::`class`,

    ];

      这样,服务端接口和启动命令都已经完成了,接下来我们继续编写客户端建立连接和请求通信代码。

    编写客户端代码

    在 客户端(client) 项目根目录下新增一个 thrift 子目录,然后在该子目录下创建 Thrift IDL 文件 org.thrift,用于定义和用户相关的服务接口(语言为 PHP,命名空间为 AppThriftOrg):

    namespace php App.Thrift.OrgThrift

    service OrgThrift {
    string routeRequest(1:i32 request)
    }

     接着在项目根目录下运行如下命令,根据上述 IDL 文件生成相关的服务代码:

    1

    thrift -r --gen php -out ./ thrift/org.thrift

    这样就会在 AppThriftOrgThrift命名空间下生成对应的服务代码:

    这个客户端并不是前端、移动端,而是相对于 RPC 服务器的 RPC 客户端,我们在 app/Services/Client 目录下创建 OrgService.php,用于存放 RPC 客户端连接与请求服务接口方法:

    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

    <?php

    namespace AppServicesClient;

    use AppThriftOrgThriftOrgThriftClient;

    use ThriftProtocolTMultiplexedProtocol;

    use ThriftExceptionTException;

    use ThriftProtocolTBinaryProtocol;

    use ThriftTransportTBufferedTransport;

    use ThriftTransportTSocket;

    class OrgService

    {

    public function routeOrg()

    {

    $request`=Request::all();`

    try {

    // 建立与 RpcServer 的连接

    $socket = new TSocket(`"127.0.0.1",` `"8001");`

    $socket`->setRecvTimeout(30000); // 超时时间`

    $socket`->setDebug(true);`

    $transport = new TBufferedTransport(`$socket`, 1024, 1024);

    $protocol = new TBinaryProtocol(`$transport`);

    $thriftProtocol = new TMultiplexedProtocol(`$protocol,` `'OrgService');`

    $client = new OrgThriftClient(`$thriftProtocol`);

    $transport`->open();`

    $result = $client`->routeRequest($request);`

    $transport`->close();`

    return $result`;`

    } catch (TException $TException`) {`

    dd(`$TException`);

    }

    }

    }

     同样,为了简化代码和流程,我这里将连接和请求代码写到一起了,如果有多个服务接口,传输层是可以共用的,需要拆分开。这里我们先建立与 RPC 服务器的连接, 

    最后,我们在 routes/web.php 中注册客户端请求路由:

    1

    2

    3

    4

    5

    6

    7

    8

    use AppServicesClientOrgService;

    Route::get(`'/org/{id}',` `function($id) {`

    $OrgService = new OrgService();

    // dd($userService);

    $Org = $OrgService`->routeOrg($id);`

    return $Org`;`

    });

    测试 RPC 服务调用

    至此,RPC 客户端和服务端代码都已经编写好了,接下来我们来测试这个 RPC 接口调用

    接下来,在项目根目录下启动 Thrift RPC 服务端:

    1

    php artisan rpc:start

      注意:
    1、根目录新建目录需配置composer.json中的psr-4
    2、取消http/kernel.php中web中间件内容

     然后composer更新:

    1

    composer dump-autoload

  • 相关阅读:
    Vue.js——60分钟快速入门
    SpringMVC--拦截器的使用
    wex5中集成的mysql数据库 打开时一闪而过 报错
    技术资源集合
    解析xml的4种方法详解
    回调方法介绍之中国好室友篇(Java示例)
    org/springframework/cache/jcache/config/AbstractJCacheConfiguration.class
    maven创建父项目和子项目
    SpringBoot学习之一 Unable to find a single main class from the following candidates
    Spring事务管理5-----声明式事务管理(3)
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13309193.html
Copyright © 2011-2022 走看看