2020年10月21日15:23:53
官方文档
https://www.grpc.io/docs/languages/php/quickstart/
先决条件
- PHP 5.5或更高版本,7.0或更高版本
- PECL
- compsoer
- PHPUnit(可选)
在Ubuntu / Debian上安装PHP和PECL:
对于PHP5:
$ sudo apt-get install php5 php5-dev php-pear phpunit
对于PHP7:
$ sudo apt-get install php7.0 php7.0-dev php-pear phpunit
要么
$ sudo apt-get install php php-dev php-pear phpunit
在CentOS / RHEL 7上安装PHP和PECL:
$ sudo rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
$ sudo rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
$ sudo yum install php56w php56w-devel php-pear phpunit gcc zlib-devel
在Mac上安装PHP和PECL:
$ brew install homebrew/php/php56-grpc
$ curl -O http://pear.php.net/go-pear.phar
$ sudo php -d detect_unicode=0 go-pear.phar
安装Composer(Linux或Mac):
$ curl -sS https://getcomposer.org/installer | php
$ sudo mv composer.phar /usr/local/bin/composer
安装PHPUnit(Linux或Mac):
$ wget https://phar.phpunit.de/phpunit-old.phar
$ chmod +x phpunit-old.phar
$ sudo mv phpunit-old.phar /usr/bin/phpunit
安装gRPC PHP扩展
有两种安装gRPC PHP扩展的方法:
pecl
build from source
使用PECL
sudo pecl install grpc
或特定版本
sudo pecl install grpc-1.7.0
警告
在Windows上安装
您可以从PECL网站下载预编译的gRPC扩展
使用gRPC C核心库从源代码构建
在给定的发行标签处克隆该存储库
$ git clone -b v1.32.0 https://github.com/grpc/grpc
构建并安装gRPC C核心库
$ cd grpc
$ git submodule update --init
$ make
$ sudo make install
构建并安装gRPC PHP扩展
编译gRPC PHP扩展
$ cd grpc/src/php/ext/grpc
$ phpize
$ ./configure
$ make
$ sudo make install
这会将gRPC PHP扩展编译并安装到标准PHP扩展目录中。您应该能够在安装了PHP扩展的情况下运行单元测试。
更新php.ini
安装GRPC扩展后,请确保您此行添加到您的php.ini
文件(例如/etc/php5/cli/php.ini
, /etc/php5/apache2/php.ini
或/usr/local/etc/php/5.6/php.ini
),这取决于您的PHP安装。
extension=grpc.so
将gRPC PHP库添加为Composer依赖项
您需要将此添加到项目的composer.json
文件中。
"require": {
"grpc/grpc": "v1.7.0"
}
要使用.proto
文件中生成的存根代码运行测试,您还需要composer
和protoc
二进制文件。您可以在下面找到如何获得这些信息。
为Mac OS X和Linux安装其他先决条件
protoc: protobuf compiler
protobuf.so: protobuf runtime library
grpc_php_plugin: Generates PHP gRPC service interface out of Protobuf IDL
安装Protobuf编译器
如果尚未安装,则需要protoc
为当前gRPC版本安装protobuf编译器 3.4.0+版本(越新越好)。如果已经安装,请确保protobuf版本与所安装的grpc版本兼容。如果从源代码构建grpc.so,则可以检查package.xml文件中的grpc版本。
下表列出了grpc和protobuf版本之间的兼容性:
grpc | 原虫 |
---|---|
v1.0.0 | 3.0.0(GA) |
v1.0.1 | 3.0.2 |
v1.1.0 | 3.1.0 |
v1.2.0 | 3.2.0 |
v1.2.0 | 3.2.0 |
v1.3.4 | 3.3.0 |
v1.3.5 | 3.2.0 |
v1.4.0 | 3.3.0 |
v1.6.0 | 3.4.0 |
如果protoc
尚未安装,则可以protoc
从协议缓冲区GitHub存储库下载二进制文件 。然后解压缩该文件,并更新环境变量PATH
以包含protoc二进制文件的路径(/ protobuf / releases)。然后解压缩该文件,并更新环境变量PATH
以包括协议二进制文件的路径。
如果确实必须protoc
从源代码进行编译,则可以运行以下命令,但是这样做很冒险,因为没有简便的方法可以将其卸载/升级到较新的版本。
$ cd grpc/third_party/protobuf
$ ./autogen.sh && ./configure && make
$ sudo make install
Protobuf运行时库
有两个protobuf运行时库可供选择。就提供的API而言,它们是相同的。C实现提供更好的性能,而本机实现更易于安装。确保已安装的protobuf版本与grpc版本兼容。
C实现(以获得更好的性能)
$ sudo pecl install protobuf
或特定版本
$ sudo pecl install protobuf-3.4.0
protobuf的扩展是通过添加此行到您的安装,更新后的php.iniphp.ini
文件(例如/etc/php5/cli/php.ini
, /etc/php5/apache2/php.ini
或/usr/local/etc/php/5.6/php.ini
),这取决于您的PHP安装。
extension=protobuf.so
PHP实现(为了更容易安装)
将此添加到您的composer.json
文件:
"require": {
"google/protobuf": "^v3.3.0"
}
PHP Protoc插件
您需要使用gRPC PHP protoc插件来生成客户端存根类。它可以根据.proto服务定义生成服务器和客户端代码。
make
从此仓库的根目录运行时,它应该已经被编译。插件可以在bins/opt
目录中找到。我们计划将来提供一种更好的方式来下载和安装插件。
您还可以通过运行以下命令来构建gRPC PHP protoc插件:
$ git clone -b v1.32.0 https://github.com/grpc/grpc
$ cd grpc
$ git submodule update --init
$ make grpc_php_plugin
插件可能会使用新的protobuf版本的新功能,因此也请确保安装的protobuf版本与您构建此插件的grpc版本兼容。
下载示例
您需要示例代码的本地副本才能完成此快速入门。从我们的GitHub存储库下载示例代码(以下命令将克隆整个存储库,但是您仅需要有关此快速入门和其他教程的示例):
请注意,当前,您只能在PHP中为gRPC服务创建客户端。使用另一种语言创建gRPC服务器。
# Clone the repository to get the example code:
$ git clone -b v1.32.0 https://github.com/grpc/grpc
# Build grpc_php_plugin to generate proto files if not build before
$ cd grpc && git submodule update --init && make grpc_php_plugin
# Navigate to the "hello, world" PHP example:
$ cd examples/php
$ ./greeter_proto_gen.sh
$ composer install
运行gRPC应用程序
从examples/node
目录:
-
运行服务器:
$ npm install $ cd dynamic_codegen $ node greeter_server.js
-
在另一个终端的
examples/php
目录中,运行客户端:$ ./run_greeter_client.sh
恭喜你!您刚刚使用gRPC运行了客户端服务器应用程序。
更新gRPC服务
现在让我们看一下如何使用服务器上的附加方法更新应用程序,以供客户端调用。我们的gRPC服务是使用协议缓冲区定义的;您可以.proto
在《基础教程》中找到更多有关如何在文件中定义服务的信息。现在,您只需要知道服务器和客户端“存根”都有一个SayHello
RPC方法,该方法HelloRequest
从客户端获取 参数并HelloResponse
从服务器返回a ,并且该方法的定义如下:
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
让我们对其进行更新,以便该Greeter
服务具有两种方法。examples/protos/helloworld.proto
使用SayHelloAgain
具有相同请求和响应类型的新方法来编辑 和更新它:
// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
// Sends another greeting
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
记住要保存文件!
生成gRPC代码
接下来,我们需要更新应用程序使用的gRPC代码以使用新的服务定义。从grpc
根目录:
$ protoc --proto_path=examples/protos
--php_out=examples/php
--grpc_out=examples/php
--plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin
./examples/protos/helloworld.proto
或在grpc/example/php
目录下运行帮助程序脚本(如果您通过源代码构建grpc-php-plugin):
$ ./greeter_proto_gen.sh
这将重新生成protobuf文件,其中包含我们生成的客户端类,以及用于填充,序列化和检索我们的请求和响应类型的类。
更新并运行应用程序
现在,我们有了新生成的客户代码,但是仍然需要在示例应用程序的人工编写部分中实现并调用新方法。
更新服务器
在同一目录中,打开greeter_server.js
。像这样实现新方法:
function sayHello(call, callback) {
callback(null, {message: 'Hello ' + call.request.name});
}
function sayHelloAgain(call, callback) {
callback(null, {message: 'Hello again, ' + call.request.name});
}
function main() {
var server = new grpc.Server();
server.addProtoService(hello_proto.Greeter.service,
{sayHello: sayHello, sayHelloAgain: sayHelloAgain});
server.bind('0.0.0.0:50051', grpc.ServerCredentials.createInsecure());
server.start();
}
...
更新客户端
在同一目录中,打开greeter_client.php
。像这样调用新方法:
$request = new HelloworldHelloRequest();
$request->setName($name);
list($reply, $status) = $client->SayHello($request)->wait();
$message = $reply->getMessage();
list($reply, $status) = $client->SayHelloAgain($request)->wait();
$message = $reply->getMessage();
运行!
就像我们之前所做的那样,从examples/node/dynamic_codegen
目录:
-
运行服务器:
$ node greeter_server.js
-
在另一个终端的
examples/php
目录中,运行客户端:$ ./run_greeter_client.sh