緊接上一篇,下面用 PHP 作爲客戶端調用 golang 的服務端。
安裝 grpc_go_plugin 插件
grpc_php_plugin
插件可以幫助我們自動生成client stub
類庫(相當於API
文件),方便我們直接引入調用,否則只生成服務/請求/響應的實體類,用起來不太方便。
# 下載 grpc 的庫到本地
cd ~ && git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc
# 更新子模塊依賴
cd grpc && git submodule update --init
# 這裏我們只編譯 php 的插件 如果要編譯所有的 make && make install
make grpc_php_plugin
# 插件路徑
ll ./bins/opt/grpc_php_plugin
生成PHP客戶端
如果要和世界上最好的語言PHP
結合使用的話(PHP
只能做C
端)只需要安裝 grpc
和protobuf
擴展,生成PHP
版的庫即可。
###生成php客戶端庫
#不會有 client stub 類
protoc -I. --php_out=plugins=grpc:./user user.proto
# 會有 client stub 類
protoc -I. \
--php_out=./user \
--grpc_out=./user \
--plugin=protoc-gen-grpc=/root/grpc/bins/opt/grpc_php_plugin \
user.proto
# 查看生成的服務類庫
[root@localhost grpc]# tree user
user
├── GPBMetadata
│ └── User.php
├── User
│ ├── UserClient.php
│ ├── UserDeleteRequest.php
│ ├── UserDeleteResponse.php
│ ├── UserEntity.php
│ ├── UserIndexRequest.php
│ ├── UserIndexResponse.php
│ ├── UserPostRequest.php
│ ├── UserPostResponse.php
│ ├── UserViewRequest.php
│ └── UserViewResponse.php
└── user.pb.go
PHP GRPC 擴展及依賴安裝
#安裝擴展
pecl install grpc
pecl install protobuf
使用 composer
管理依賴加載。
mkdir grpc-php-client && cd grpc-php-client
# 使用 composer 管理項目
composer init
# 安裝 grpc/protobuf 的客戶端庫文件
composer require grpc/grpc
composer require google/protobuf
# 新建 grpc 服務庫目錄 將生成的PHP客戶端文件移動至此
mkdir grpc && mv $GOPATH/src/grpc/user/* ./grpc
# 註冊 psr4 自動加載服務的客戶端文件
vi composer.json
{
"name": "root/php-client",
"require": {
"grpc/grpc": "^1.19",
"google/protobuf": "^3.7"
},
"autoload": {
"psr-4": {
"User\\": "./grpc/User/",
"GPBMetadata\\": "./grpc/GPBMetadata/"
}
}
}
# 更新 composer 加載器
composer dump-autoload
PHP客戶端代碼實例
在安裝完php
的grpc
擴展和依賴庫後,我們就可以編寫代碼了。
<?php
require_once __DIR__ . '/vendor/autoload.php';
use User\UserClient;
use User\UserEntity;
use User\UserIndexRequest;
use User\UserIndexResponse;
use User\UserViewRequest;
use User\UserViewResponse;
use User\UserPostRequest;
use User\UserPostResponse;
use User\UserDeleteRequest;
use User\UserDeleteResponse;
// 創建客戶端實例
$userClient = new UserClient('10.10.31.211:50051', [
'credentials' => Grpc\ChannelCredentials::createInsecure()
]);
$userIndexRequest = new UserIndexRequest();
$userIndexRequest->setPage(1);
$userIndexRequest->setPageSize(12);
// 發送請求 返回的是一個數組 [服務接口對應的響應對象, 請求狀態對象]
list($userIndexResponse, $statusObj) = $userClient->UserIndex($userIndexRequest)->wait();
if (0 != $statusObj->code) {
throw new \Exception($statusObj->details, $statusObj->code);
}
echo printf("index request end: err %d msg %s" . PHP_EOL, $userIndexResponse->getErr(), $userIndexResponse->getMsg());
/* @var [UserEntity, UserEntity] */
$data = $userIndexResponse->getData();
foreach ($data as $row) {
echo $row->getName(), $row->getAge() . PHP_EOL;
}
// 剩餘的就不寫了 都很簡單的
// $userClient->UserView();
// $userClient->UserPost();
// $userClient->UserDelete();