{"id":13700002,"url":"https://github.com/mix-php/grpc","last_synced_at":"2025-08-20T06:32:08.952Z","repository":{"id":47362671,"uuid":"254868278","full_name":"mix-php/grpc","owner":"mix-php","description":"PHP gRPC based on Swoole coroutine, including protoc code generator, server, and client / 基于 Swoole 协程的 PHP gRPC 库，包含 protoc 代码生成器、服务器、客户端","archived":false,"fork":false,"pushed_at":"2024-06-06T11:14:28.000Z","size":93,"stargazers_count":56,"open_issues_count":0,"forks_count":10,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-11-30T11:56:35.817Z","etag":null,"topics":["grpc","mix","protoc-gen","swoole"],"latest_commit_sha":null,"homepage":"https://openmix.org/mix-php","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mix-php.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-11T12:58:33.000Z","updated_at":"2024-11-08T13:40:31.000Z","dependencies_parsed_at":"2023-11-06T03:28:54.465Z","dependency_job_id":"34fde134-019a-4835-8552-7f99337ab1e7","html_url":"https://github.com/mix-php/grpc","commit_stats":{"total_commits":98,"total_committers":4,"mean_commits":24.5,"dds":"0.030612244897959218","last_synced_commit":"997d1e0581a46ddd4e860d2ab1bd01284b80ced6"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mix-php%2Fgrpc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mix-php%2Fgrpc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mix-php%2Fgrpc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mix-php%2Fgrpc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mix-php","download_url":"https://codeload.github.com/mix-php/grpc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230400606,"owners_count":18219830,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["grpc","mix","protoc-gen","swoole"],"created_at":"2024-08-02T20:00:46.982Z","updated_at":"2024-12-19T08:07:48.684Z","avatar_url":"https://github.com/mix-php.png","language":"PHP","funding_links":[],"categories":["gRPC"],"sub_categories":[],"readme":"\u003e OpenMix 出品：[https://openmix.org](https://openmix.org/mix-php)\n\n# Mix gRPC\n\nPHP gRPC based on Swoole coroutine, including protoc code generator, server, and client\n\n基于 Swoole 协程的 PHP gRPC 库，包含 protoc 代码生成器、服务器、客户端\n\n## Overview\n\n由于 PHP-FPM 的特殊生命周期，导致 PHP 的 gRPC 官方代码生成器只能生成数据结构和客户端代码，无法像 golang/node.js/python 一样能同时生成服务器代码；传统方式如果要搭建 PHP gRPC 服务器只能借助\nnginx+h2+phpfpm 来搭建，这样就不需要 server 代码了，但是短生命周期又无法很好的支持服务注册，因为这些原因导致 PHP 在 gRPC 中一直都是充当 Client 的角色，Mix gRPC 提供了基于 Swoole\n的方案：\n\n- 使用 [Swoole](https://github.com/swoole/swoole-src) 作为 gRPC Server\n- 使用 Golang 打造的 protoc-gen-mix 来生成 service 的 server/client 代码\n- 完全独立，可在任何 CLI 模式的 php 代码中执行，任何框架的 CLI 模式中执行 Laravel、ThinkPHP、MixPHP 等都可以\n- 同时为了降低门槛，我已经将 protoc、protoc-gen-mix 文件编译好了 win、linux、macOS 三个系统的二进制文件，直接下载即可\n\n让 PHP 编写 gRPC 和 Golang 一样方便快捷，同时性能强劲\n\n**推荐搭配以下数据库使用 (支持协程和连接池)：**\n\n- https://github.com/mix-php/database\n- https://github.com/mix-php/redis\n\n## 技术交流\n\n知乎：https://www.zhihu.com/people/onanying    \n官方QQ群：[284806582](https://shang.qq.com/wpa/qunwpa?idkey=b3a8618d3977cda4fed2363a666b081a31d89e3d31ab164497f53b72cf49968a)\n, [825122875](http://shang.qq.com/wpa/qunwpa?idkey=d2908b0c7095fc7ec63a2391fa4b39a8c5cb16952f6cfc3f2ce4c9726edeaf20)\n敲门暗号：grpc\n\n## Installation\n\n- Swoole \u003e= 4.4.4: https://wiki.swoole.com/#/environment\n- 需要开启 `--enable-http2`\n\n```\ncomposer require mix/grpc\n```\n\n## 下载 protoc 与相关 plugin\n\n- [protoc](https://github.com/protocolbuffers/protobuf) 是 protobuf 数据结构代码生成器，负责将 .proto 数据结构文件生成为对应语言的 class、struct\n  供程序使用，\n- [protoc-gen-mix](https://github.com/mix-php/grpc/tree/master/protoc-gen-mix) 是 mix 开发的 protoc 插件，用来生成 service 的\n  server/client 代码。\n\n以上 2 个二进制文件，我都帮你们编译好了，包含多个常用 OS 类型，直接下载即可：\n\n- [下载 protoc_mix_plugin](https://github.com/mix-php/grpc/releases/tag/binary-210714) `win/macos/linux`\n\n下载完成后 linux、macOS 将二进制文件放入系统 `/usr/local/bin` 目录，win 放入 `C:\\WINDOWS\\system32`\n\n## 通过 .proto 生成 PHP 代码\n\n首先我们编写一个 proto 文件：\n\n```\nsyntax = \"proto3\";\n\npackage php.micro.grpc.greeter;\n\nservice Say {\n\trpc Hello(Request) returns (Response) {}\n}\n\nmessage Request {\n\tstring name = 1;\n}\n\nmessage Response {\n\tstring msg = 1;\n}\n```\n\n然后使用 protoc 生成代码：\n\n```\nprotoc --php_out=. --mix_out=. greeter.proto\n```\n\n执行命令后将在当前目录生成以下文件：\n\n```\n|-- GPBMetadata\n|   `-- Greeter.php\n|-- Php\n|   `-- Micro\n|       `-- Grpc\n|           `-- Greeter\n|               |-- Request.php\n|               |-- Response.php\n|               |-- SayClient.php\n|               `-- SayInterface.php\n`-- greeter.proto\n```\n\n其中 Request.php、Response.php 为 `--php_out` 生成，SayClient.php SayInterface.php 由 `--mix_out` 生成。\n\n接下来我们将生成的文件加入到 composer autoload 中，我们修改 composer.json：\n\n```\n\"autoload-dev\": {\n    \"psr-4\": {\n        \"GPBMetadata\\\\\": \"protodir/GPBMetadata/\",\n        \"Php\\\\\": \"protodir/Php/\"\n    }\n}\n```\n\n修改后执行 `composer dump-autoload` 使其生效。\n\n## 编写一个 gRPC 服务\n\n我们用原生 PHP 代码来编写一个 gRPC 服务器：\n\n```php\n// 编写一个服务，实现 protoc-gen-mix 生成的接口\nclass SayService implements Php\\Micro\\Grpc\\Greeter\\SayInterface\n{\n\n    public function Hello(Mix\\Grpc\\Context $context, Php\\Micro\\Grpc\\Greeter\\Request $request): Php\\Micro\\Grpc\\Greeter\\Response\n    {\n        $response = new Php\\Micro\\Grpc\\Greeter\\Response();\n        $response-\u003esetMsg(sprintf('hello, %s', $request-\u003egetName()));\n        return $response;\n    }\n\n}\n\n$grpc = new Mix\\Grpc\\Server();\n$grpc-\u003eregister(SayService::class); // or $grpc-\u003eregister(new SayService());\n```\n\nSwoole 多进程 (异步) 中使用\n\n```php\n$http = new Swoole\\Http\\Server('0.0.0.0', 9595);\n$http-\u003eon('Request', $grpc-\u003ehandler());\n$http-\u003eset([\n    'worker_num' =\u003e 4,\n    'open_http2_protocol' =\u003e true,\n    'http_compression' =\u003e false,\n]);\n$http-\u003estart();\n```\n\n开启多进程协程\n\n```php\n$http-\u003eon('Request', $grpc-\u003ehandler());\n$http-\u003eon('WorkerStart', function ($server, $workerId) {\n    // 协程初始化\n    // 比如：启动 mix/database mix/redis 的连接池\n});\n$http-\u003eset([\n    'enable_coroutine' =\u003e true,\n    'worker_num' =\u003e 4,\n    'open_http2_protocol' =\u003e true,\n    'http_compression' =\u003e false,\n]);\n```\n\nSwoole 单进程 (协程) 中使用\n\n```php\nSwoole\\Coroutine\\run(function () use ($grpc) {\n    $server = new Swoole\\Coroutine\\Http\\Server('0.0.0.0', 9595, false);\n    $server-\u003ehandle('/', $grpc-\u003ehandler());\n    $server-\u003eset([\n      'open_http2_protocol' =\u003e true,\n      'http_compression' =\u003e false,\n    ]);\n    $server-\u003estart();\n});\n```\n\n## 客户端调用一个 gRPC 服务\n\n通过 IP 端口调用 gRPC 服务，复用客户端时请注意：[协程环境中，不可在并发请求中使用单例](https://openmix.org/mix-php/docs/3.0/#/zh-cn/instructions?id=%e5%8d%8f%e7%a8%8b%e5%8d%95%e4%be%8b%e5%ae%9e%e4%be%8b%e5%8c%96)\n\n```php\nSwoole\\Coroutine\\run(function () {\n    $client = new Mix\\Grpc\\Client('127.0.0.1', 9595); // 推荐复用该客户端\n    $say  = new Php\\Micro\\Grpc\\Greeter\\SayClient($client);\n    $request = new Php\\Micro\\Grpc\\Greeter\\Request();\n    $request-\u003esetName('xiaoming');\n    $ctx = new Mix\\Grpc\\Context();\n    $response = $say-\u003eHello($ctx, $request);\n    var_dump($response-\u003egetMsg());\n    $client-\u003eclose(); // 使用完必须关闭，否则会残留在内存\n});\n```\n\n设置 `header`\n\n```php\n$ctx-\u003ewithHeader('foo', 'bar');\n$response = $say-\u003eHello($ctx, $request);\n```\n\n设置 `timeout`\n\n```php\n$ctx-\u003ewithTimeout(5.0);\n$response = $say-\u003eHello($ctx, $request);\n```\n\n## FPM 如何调用 gRPC 服务\n\n像我们传统 PHP FPM 模式中，我们作为客户端调用 gRPC 比 Mix gRPC 提供的客户端要复杂很多，但是我们也经常需要用到，比如在 thinkphp laravel 中调用 Mix gRPC 或者 Mix Go 编写的 gRPC\n服务，推荐阅读以下文章：\n\n- [gRPC入坑记](https://www.cnblogs.com/52fhy/p/11110704.html#php%E7%9B%B8%E5%85%B3%E6%94%AF%E6%8C%81)\n- [PHP中使用gRPC客户端](https://bbs.huaweicloud.com/blogs/135609)\n\n网上的文章都缺少重要的一环，就是：\n\n```\nprotoc --php_out=. greeter.proto\n```\n\n命令执行时，只会生成数据结构的 class 文件，不会生成 grpc 服务的客户端 class 文件\n\n```\nservice Say {\n\trpc Hello(Request) returns (Response) {}\n}\n```\n\n以上服务没有被处理，没有生成出 `SayClient.php` ，需要修改编译命令\n\n```\nprotoc --php_out=. --grpc_out=. --plugin=protoc-gen-grpc=/path/grpc_php_plugin greeter.proto\n```\n\n命令中指定了一个 `grpc_php_plugin` 文件是由 [grpc/grpc](https://github.com/grpc/grpc/tree/master/src/php) 提供的源码，官方没有像 `protoc`\n一样提供编译好的二进制可以下载，只能自己编译。然而这个库依赖的大量的子仓库，在国内几乎无法拉取成功，其次 win 的 cmake 编译很多人不会弄，导致大量的人无法编译出这个文件，因此我这里直接提供编译好的二进制供大家下载。\n\n- [下载 protoc_grpc_plugin](https://github.com/mix-php/grpc/releases/tag/binary-210714) `win/macos/linux`\n\n## License\n\nApache License Version 2.0, http://www.apache.org/licenses/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmix-php%2Fgrpc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmix-php%2Fgrpc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmix-php%2Fgrpc/lists"}