php需要这个额外的protoc、grpc_php_plugin工具把这个protobuf格式的文件生成php语言里的类
go需要安装protoc-gen-go工具把protobuf格式的接口定义文件生成go语言里的类定义
java无需手动安装额外工具,有maven即可,再次体现了java的优越性(
github.com/protocolbuf…
解压后,把bin目录放到PATH里面
构建参考
git clone https://github.com/grpc/grpc.git cd grpc brew install autoconf automake libtool shtool LIBTOOL=glibtool LIBTOOLIZE=glibtoolize make -j8 复制代码
grpc源码库较大,可以直接开8核进行编译 编译好的grpc_php_plugin在bins/opt/目录下,把grpc_php_plugin放到PATH里面
扩展的地址: pecl.php.net/package/gRP…
项目地址: github.com/golang/prot…
git clone https://github.com/golang/protobuf.git cd protobuf/protoc-gen-go go build 复制代码
操作效果如下
把这个生成的protoc-gen-go放到PATH
go: 提供grpc服务端,提供一个sayHello的接口,参数为代表名字的字符串,返回值为 “Hello"拼接上这个名字 java和php作为客户端调用这个go的客户端
"golang.org/x/net/context" "google.golang.org/grpc" "google.golang.org/grpc/reflection" 复制代码
<dependency> <groupId>io.grpc</groupId> <artifactId>grpc-netty</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-protobuf</artifactId> <version>1.0.0</version> </dependency> <dependency> <groupId>io.grpc</groupId> <artifactId>grpc-stub</artifactId> <version>1.0.0</version> </dependency> 复制代码
"grpc/grpc": "^v1.9", "google/protobuf": "^v3.5" 复制代码
syntax = "proto3"; option go_package = "pbf"; package helloworld; // The greeting service definition. service Hello { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloResponse) {} } // The request message containing the user's name. message HelloRequest { string name = 1; } // The response message containing the greetings message HelloResponse { string message = 1; } 复制代码
这个protobuf文件定义了两个数据结构,HelloRequest和HelloResponse,和一个SayHello的接口
使用下面的命令把这个proto文件编译成对应的php和go的数据结构
#!/bin/bash for file in ./protos/*.proto; do echo "生成对应的php类文件: $file" protoc -I ./protos --php_out=./php/pbf --grpc_out=./php/pbf --plugin=protoc-gen-grpc=$(which grpc_php_plugin) $file done protoc -I ./protos --go_out=plugins=grpc:./go/pbf ./protos/*.proto 复制代码
// helloServer implements helloworld.HelloServer type helloServer struct{} // SayHello implements helloworld.HelloServer func (s *helloServer) SayHello(ctx context.Context, in *pbf.HelloRequest) (*pbf.HelloResponse, error) { return &pbf.HelloResponse{Message: "Hello " + in.Name}, nil } func main() { s := grpc.NewServer() pbf.RegisterHelloServer(s, &helloServer{}) reflection.Register(s) s.Serve(lis) } 复制代码
func (s *helloServer) SayHello(ctx context.Context, in *pbf.HelloRequest) (*pbf.HelloResponse, error)
里面就是SayHello这个接口的具体实现了
$name = '小明'; $client = new Helloworld/HelloClient('localhost:8488', [ 'credentials' => Grpc/ChannelCredentials::createInsecure(), ]); $request = new Helloworld/HelloRequest(); $request->setName($name); list($response, $status) = $client->SayHello($request)->wait(); echo '服务端返回状态码: ' . $status->code . PHP_EOL; echo "服务器端回复内容:" . $response->getMessage() . PHP_EOL; 复制代码
code 0表示正常
private final HelloGrpc.HelloBlockingStub blockingStub; public HelloClient(String host, int port) { //初始化连接 channel = ManagedChannelBuilder.forAddress(host, port) .usePlaintext(true) .build(); //初始化远程服务Stub blockingStub = HelloGrpc.newBlockingStub(channel); } public String sayHello(String name) { //构造服务调用参数对象 Helloworld.HelloRequest request = Helloworld.HelloRequest.newBuilder().setName(name).build(); //调用远程服务方法 Helloworld.HelloResponse response = blockingStub.sayHello(request); //返回值 return response.getMessage(); } 复制代码
sayHello()
里就是通过grpc调用go的sayHello方法。
可以看到,这三个程序都ok了