## gRPC
[gRPC](http://link.zhihu.com/?target=https%3A//github.com/grpc/grpc) 是谷歌基于 [Protobuf](https://github.com/protocolbuffers/protobuf) + Http2 研發的 RPC 通用框架,幾乎支持流行的全部語言,該框架使用 .proto 文件定義交互的數據結構,并通過 protoc 代碼生成器生成對應語言的代碼進行交互。
## PHP gRPC 現狀
由于官方的 protoc 生成器里生成的 PHP 代碼只有 Client 代碼,這個是因為 PHP 流行的是短生命周期 phpfpm 搭建 Server 時是通過 nginx+h2+phpfpm 這種方式,因此也就不需要 Server 代碼了,加上生成的 Client 代碼使用的是 phpgrpc 擴展,由于使用的多線程技術,導致 Swoole 無法 Hook 因此無法使用協程。
## Mix gRPC
由于以上問題,Mix 直接拋棄了 phpgrpc 擴展,直接通過 Swoole + [Protobuf](https://github.com/protocolbuffers/protobuf) 打造 gRPC 的 Server/Client ,為了和 go-micro 編寫微服務的體驗一致,Mix 開發 [protoc-gen-mix](https://github.com/mix-php/grpc/tree/master/protoc-gen-mix) 插件,能通過 .proto 文件直接生成 Service 的 Server/Client 代碼,該庫是獨立的,能在任何框架或原生代碼中使用。
## 組件
使用 [composer](https://www.phpcomposer.com/) 安裝:
```
composer require mix/grpc
```
## 依賴注入配置
- [manifest/beans/grpc.php](https://github.com/mix-php/mix-micro-skeleton/blob/master/manifest/beans/grpc.php)
## 下載 protoc 與相關 plugin
- [protoc](https://github.com/protocolbuffers/protobuf) 是 protobuf 數據結構代碼生成器,負責將 .proto 數據結構文件生成為對應語言的 class、struct 供程序使用,
- [protoc-gen-mix](https://github.com/mix-php/grpc/tree/master/protoc-gen-mix) 是 mix 開發的 protoc 插件,用來生成 service 的 server/client 代碼。
以上 2 個二進制文件,我都幫你們編譯好了,包含多個常用 OS 類型,直接下載即可:
- [https://github.com/mix-php/grpc/releases/tag/binary](https://github.com/mix-php/grpc/releases/tag/binary)
下載完成后 linux、macOS 將二進制文件放入系統 `/usr/local/bin` 目錄,win 放入 `C:\WINDOWS\system32`
## 生成代碼
首先我們編寫一個 proto 文件:
```
syntax = "proto3";
package php.micro.grpc.greeter;
service Say {
rpc Hello(Request) returns (Response) {}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
```
然后使用 protoc 生成代碼:
- Linux/Mac
```
protoc --php_out=. --mix_out=. greeter.proto
```
- Win
```
protoc.exe --php_out=. --mix_out=. greeter.proto
```
執行命令后將在當前目錄生成以下文件:
```
|-- GPBMetadata
| `-- Greeter.php
|-- Php
| `-- Micro
| `-- Grpc
| `-- Greeter
| |-- Request.php
| |-- Response.php
| |-- SayClient.php
| `-- SayInterface.php
`-- greeter.proto
```
其中 Request.php、Response.php 為 `--php_out` 生成,SayClient.php SayInterface.php 由 `--mix_out` 生成。
接下來我們將生成的文件加入到 composer autoload 中,我們修改 composer.json:
```
"autoload-dev": {
"psr-4": {
"GPBMetadata\\": "protos/GPBMetadata/",
"Php\\": "protos/Php/"
}
}
```
修改后執行 `composer dump-aotoload` 使其生效。
## 服務器
我們用原生 php 代碼來編寫一個 gRPC 服務器:
```
// 編寫一個服務,實現 protoc-gen-mix 生成的接口
class SayService implements \Php\Micro\Grpc\Greeter\SayInterface
{
public function Hello(\Mix\Context\Context $context, \Php\Micro\Grpc\Greeter\Request $request): \Php\Micro\Grpc\Greeter\Response
{
$response = new \Php\Micro\Grpc\Greeter\Response();
$response->setMsg(sprintf('hello, %s', $request->getName()));
return $response;
}
}
// 創建一個服務器
$server = new \Mix\Grpc\Server('0.0.0.0', 9595); // 默認會隨機分配端口,也可以指定
$server->register(SayService::class);
$server->start();
```
## 客戶端
接下來我們用另一個 php 文件來編寫一個客戶端程序:
```
// 撥號一個連接
$dialer = new \Mix\Grpc\Client\Dialer();
$conn = $dialer->dial('127.0.0.1', 9595);
// 通過連接創建客戶端
$client = new \Php\Micro\Grpc\Greeter\SayClient($conn);
// 發送請求
$request = new \Php\Micro\Grpc\Greeter\Request();
$request->setName('xiaoming');
$response = $client->Hello($request);
// 打印結果
var_dump($response->getMsg());
```
- 歡迎使用 MixPHP
- 安裝說明
- 全棧開發
- 微服務開發
- Phar 開發
- 如何部署
- 獨立部署
- Nginx
- Supervisord
- 新手教程
- 命令行常識
- 進程管理
- 熱更新
- 全局變量
- 調試程序
- 入門須知
- 命名空間
- 自動加載
- 入口文件
- 增改應用
- 自動補全 IDE
- 核心功能
- 配置 (manifest.php)
- 依賴注入
- 事件調度
- 驗證器
- 驗證器定義
- 驗證規則
- 靜態調用
- 日志 Monolog
- 緩存
- 協程
- 什么是協程
- 開啟協程
- Runtime
- 簡介
- 創建協程 xgo + Channel
- 創建協程 xgo + WaitGroup
- xgo
- xdefer
- Channel
- WaitGroup
- Timer + Ticker
- Signal
- Select
- Context
- WorkerPool
- 數據庫
- Database
- Database
- Connection
- QueryBuilder
- ExecutedEvent
- Redis
- Redis
- Connection
- CalledEvent
- 命令行
- 簡介
- Application
- 創建命令
- 命令參數
- 打印與顏色
- 守護進程
- 后臺運行
- Web/API 應用
- 簡介
- 編寫一個接口
- 服務器
- 路由 FastRoute
- 中間件
- 請求
- 響應
- 文件上傳
- 控制器
- 視圖
- Auth
- Session
- Guzzle
- HTTP 404/500
- 安全建議
- WebSocket 應用
- 簡介
- 服務器
- 客戶端
- Client
- JavaScript
- Swoole
- nginx代理
- 60s無消息斷線
- Micro 微服務
- 簡介
- 編寫一個微服務
- Mix Micro
- Go Micro
- gRPC
- JSON-RPC
- 服務注冊
- 配置中心
- 熔斷與降級
- 調用鏈追蹤
- 服務限流
- Sync Invoke 同步調用
- 簡介
- 服務器
- 客戶端
- TCP 應用
- 簡介
- 服務器
- 客戶端
- Telnet
- PHP
- Swoole
- UDP 應用
- 簡介
- 服務器
- 客戶端
- NC
- Swoole
- 第三方接入
- EasyWeChat
- Sentry
- Doctrine Cache
- 常見問題
- 如何利用 CPU 多核
- 連接多個數據庫
- 如何設置跨域
- form-data 上傳文件失敗
- 輸出大于 2M 的文件失敗