緊接上一篇,下面用PHP
做爲客戶端調用Go
的服務端。php
grpc_php_plugin
插件能夠幫助咱們自動生成client stub
客戶端(封裝了grpc
的服務接口),方便咱們直接引入調用,不然只生成服務/請求/響應的實體類,用起來不太方便。git
# 下載 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
只能作C
端,且須要安裝grpc
和protobuf
擴展和庫。github
###生成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
#安裝擴展 pecl install grpc pecl install protobuf
使用 composer
管理依賴加載。json
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
的grpc
擴展和依賴庫後,咱們就能夠編寫代碼了。segmentfault
<?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); /* @var $userIndexResponse UserIndexResponse */ /* @var $statusObj stdClass */ list($userIndexResponse, $statusObj) = $userClient->UserIndex($userIndexRequest)->wait(); if (0 != $statusObj->code) { throw new \Exception($statusObj->details, $statusObj->code); } printf("index request end: err %d msg %s" . PHP_EOL, $userIndexResponse->getErr(), $userIndexResponse->getMsg()); /* @var $data UserEntity[] */ $data = $userIndexResponse->getData(); foreach ($data as $row) { echo $row->getName() . " " . $row->getAge() . PHP_EOL; } // 剩餘的就不寫了 都很簡單的 // $userClient->UserView(); // $userClient->UserPost(); // $userClient->UserDelete();
# 結果 [root@localhost php-client]# php index.php index request end: err 0 msg success big_cat 28 sqrt_cat 29
Go 服務端和客戶端版composer
grpc
使用protobuf
做爲IDL
,聲明服務接口,請求實體,響應實體,後續咱們將本身業務填充進去,客戶端發送請求實體,服務端服務接口處理業務,而後返回響應實體,請求/響應實體的數據傳輸也使用protobuf
進行了打包/解包。curl
# 打包 //\Google\Protobuf\Internal\Message::serializeToString # 解包 //\Google\Protobuf\Internal\Message::mergeFromString // 客戶端 $message = new Message(); $message->setId(1); $message->setName("sqrt_cat"); $message->setAddress("shanghai"); $package = $message->serializeToString(); // 發送 $package 至服務端 // 服務端接收數據後使用對應的實體解包 // 服務端 $message = new Message(); $message->mergeFromString($package); var_dump($message->getId(), $message->getName(), $message->getAddress());