前言
最近写项目的时候碰到一些api接口需要使用gRPC调用,本着php是世界上最好的语言的前提,简单研究了一下使用方法。
扩展安装
直接使用pecl命令编译,简单省事,如需手动编译建议自行谷歌。
将此行添加到 php.ini 文件中的任意位置,例如 /etc/php/php.ini。
protoc编译器安装
1 2
| sudo apt-get update sudo apt-get install -y cmake git make g++
|
需要把这几个命令安装好才可以进行下一步的编译,Debian、Ubuntu可以直接使用上面的命令,Redhat系把apt-get换成yum,Aphine就换成apk add命令。
1 2 3 4 5 6 7
| git clone https://github.com/grpc/grpc cd grpc git submodule update --init mkdir -p cmake/build cd cmake/build cmake ../.. make protoc grpc_php_plugin
|
protobuf:编译器二进制文件,用于为消息和服务定义生成PHP类。
grpc_php_plugin:protoc的插件,用于生成服务存根类。
1 2
| mv third_party/protobuf/protoc /usr/local/bin/protoc mv grpc_php_plugin /usr/local/bin/grpc_php_plugin
|
将二进制文件移动到/usr/local/bin目录。
使用protoc 构建php代码
在上层目录创建src目录,用于存储生成的php代码
1
| protoc --proto_path=./ --php_out=../src --grpc_out=../src --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin $(find . -type f -name "*.proto")
|
这个命令使用了grpc_php_plugin可以自动生成客户端代码,如果没有安装grpc_php_plugin的话需要手动编写客户端代码,具体代码如下。
protobuf代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| syntax = "proto3"; package Services.Base.HelloWorld;
service HelloWorldService { rpc Demo (HelloWorldRequest) returns (HelloWorldResponse); }
message HelloWorldRequest { string name = 1; }
message HelloWorldResponse { string message = 1; }
|
客户端代码
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
| namespace App;
use Grpc\BaseStub;
use Services\Base\HelloWorld\HelloWorldRequest; use Services\Base\HelloWorld\HelloWorldResponse;
class Client extends BaseStub { public function __construct($hostname, $opts, $channel = null) { parent::__construct($hostname, $opts, $channel); }
public function Demo(HelloWorldRequest $argument, $metadata = [], $options = []) { return $this->_simpleRequest('/Services.Base.HelloWorld.HelloWorldService/Demo', $argument, [HelloWorldResponse, 'decode'], $metadata, $options); }
}
|
调用gRPC代码
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
| <?php
namespace App;
use Grpc\ChannelCredentials; use Services\Base\HelloWorld\HelloWorldRequest;
class App { public $client;
public static function run() { (new self())->grpc()->Main(); }
public function grpc() { $this->client = $this->client(); return $this; }
public function client() { return new client('127.0.0.1:8000', [ 'credentials' => ChannelCredentials::createInsecure(), ]); }
public function Main() { $request = new HelloWorldRequest(); $request->setName("林逸博客"); $get = $this->client->Demo($request)->wait(); list($reply, $status) = $get; if($status->code === 0) { print_r($reply->getMessage()); } echo '获取返回内容失败'; }
}
|
完整Demo
https://github.com/zihelyu/php-grpc-client