PHP客户端环境
本人使用为debian系统下的docker容器安装的php-fpm镜像,php-fpm7.1.13镜像承载系统为alpine;
需要安装工具
protoc: 将proto文件生成为php文件的编译器
grpc_php_plugin: protoc生成关于grpc的php文件的插件
grpc.so: php的grpc扩展
protobuf.so: php的protobuf扩展
debian系统安装protoc
下载地址:https://github.com/protocolbuffers/protobuf/releases 选择对应安装版本下载之后解压;
将解压的后的 bin/protoc 文件添加到环境变量目录里;
通过命令:
root@iZ2zebyhcs68uwq5kc8ioxZ:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin
可以看到所有的环境变量目录;
运行代码:
[root@VM_179_192_centos ~]# protoc --version
libprotoc 3.6.1
表示成功;
debian系统安装grpc_php_plugin插件
先创建个目录存放将要git下来的grpc文件 例如:/app/grpcDemo
$ cd /app/
$ git clone -b $(curl -L https://grpc.io/release) https://github.com/grpc/grpc grpcDemo
$ cd grpcDemo
$ git submodule update --init
$ make grpc_php_plugin
执行成功后会在grpc的bins/opt 目录中看到grpc_php_plugin插件,在后面protoc生成grpc的php文件时会用到;
alpine系统内grpc.so安装
使用pecl安装即可,当然如果想要自己编译,也可以
$ pecl install grpc
一般会缺少一些编译工具,所以最好先安装对应编译工具
$ apk add --no-cache libstdc++
$ apk add --no-cache --update git make g++ unzip autoconf automake libtool file openssl curl
参考:https://github.com/c9s/alpine-grpc-dev/blob/master/edge/Dockerfile
安装 grpc成功后,默认的grpc.so文件已放在对应目录内,此时需要在php.ini内引入grpc.so扩展文件
$ vi /usr/local/etc/php/conf.d/docker-php-ext-grpc.ini
extension=grpc.so
alpine系统内protobuf.so安装
同上和grpc.so类似安装
$ pecl install protobuf
安装 protobuf成功后,默认的protobuf.so文件已放在对应目录内,此时需要在php.ini内引入protobuf.so扩展文件
$ vi /usr/local/etc/php/conf.d/docker-php-ext-protobuf.ini
extension=protobuf.so
注意:为了能够使用grpc扩展,还需要在项目里composer安装grpc文件才行,运行php项目需要使用此vendor
composer require grpc/grpc
PHP客户端程序部署
protoc生成php文件
作为demo的proto文件helloworld.proto
syntax = "proto3";
package helloworld;
// 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;
}
只生成proto文件的话,不需要grpc_php_plugin插件,使用命令:
protoc --php_out=./ helloworld.proto
上面的方法只生成所有的proto对应的类,不生成实现grpc接口的stub client类。 使用下面的方法能同时生成stup client类
protoc --php_out=./ --grpc_out=./ --plugin=protoc-gen-grpc=/app/grpcDemo/bins/opt/grpc_php_plugin helloworld.proto
php程序实现:thinkphp5.1.16语法
namespace app\proto\controller;
/**
* Description of Demo
* Date 2018年11月11日 13:22:05
* @author Carter
*/
use Helloworld\GreeterClient;
use GPBMetadata\Helloworld;
use Helloworld\HelloRequest;
use Helloworld\HelloReply;
class Demo{
//grpc客户端实现
public function greet()
{
debug('begin');
$client = new GreeterClient('***.**.**.**:50051', ['credentials' => \Grpc\ChannelCredentials::createInsecure(),]);
$request = new HelloRequest();
$name = "world";
$request->setName($name);
list($reply, $status) = $client->SayHello($request)->wait();
$message = $reply->getMessage();
debug('end');
echo "消耗时间:".debug('begin','end').'s'."\n";
echo "消耗内存:".debug('begin','end','m')."\n";
echo $message."\n";
}
}
go服务端环境
本人使用服务器为centos7.2,配合go1.9.2环境
需要安装的工具
go环境安装:1.9.2版本
grpc和protobuf资源包:相当于扩展
protoc: 将proto文件生成为go文件的编译器
go环境安装
$ wget https://www.golangtc.com/static/go/1.9.2/go1.9.2.linux-amd64.tar.gz
解压到某目录,我这里解压到/usr/local/go目录;
然后将此目录添加为环境变量目录
设置环境变量
$ vim /etc/profile
添加
export GOROOT=/usr/local/go //安装目录
export GOPATH=/app/goDemo //项目目录
export PATH=$PATH:$GOROOT/bin:$GOPATH/bin //项目执行文件目录
保存
esc
:wq
创建项目目录 /app/goDemo,以及附属的子目录 src,bin,pkg;
执行命令:
[root@VM_179_192_centos go]# go version
go version go1.9.2 linux/amd64
grpc和protobuf资源包
go get https://github.com/golang/protobuf
go get https://github.com/grpc/grpc-go
protoc安装
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/protoc-gen-go
编译helloworld.proto文件生成对应go文件
protoc --go_out=plugins=grpc:. helloworld.proto
go服务端程序部署
在 /app/goDemo/src下新建greeter_server/main.go文件 代码:
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
pb "helloworld"
"google.golang.org/grpc/reflection"
)
const (
port = ":50051"
)
// server is used to implement helloworld.GreeterServer.
type server struct{}
// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}
func main() {
lis, err := net.Listen("tcp", port)
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
s := grpc.NewServer()
pb.RegisterGreeterServer(s, &server{})
// Register reflection service on gRPC server.
reflection.Register(s)
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
注意:因为翻墙原因,程序引入的一些包不会成功,所以需要自己从github查找到对应的资源,放在这些资源包里;
例如:
go get https://github.com/grpc/grpc-go google.golang.org/grpc
然后就可以运行服务端程序了
go run main.go
对应的php客户端开始访问即可:
http://***.**.**.**/proto/demo/greet
返回结果:
消耗时间:0.051832s 消耗内存:12.79 KB Hello world
go客户端环境测试
go客户端代码:使用http包测go客户端也可以,使用程序测也可以,这里使用启动go客户端启动http服务后,测http请求
go客户端代码
新建 greeter_cient/main.go 文件
package main
import (
"context"
"log"
"os"
"time"
"net/http"
"google.golang.org/grpc"
pb "helloworld"
)
const (
address = "localhost:50051"
defaultName = "world"
)
func sayhelloName(w http.ResponseWriter,r *http.Request) {
// Set up a connection to the server.
conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
c := pb.NewGreeterClient(conn)
// Contact the server and print out its response.
name := defaultName
if len(os.Args) > 1 {
name = os.Args[1]
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
if err != nil {
log.Fatalf("could not greet: %v", err)
}
log.Printf("GreetingGreeting: %s", r.Message)
}
func main(){
http.HandleFunc("/",sayhelloName) //设置访问的路由
err := http.ListenAndServe(":9090",nil) //设置监听的端口
if err != nil{
log.Fatal("ListenAndServe:",err)
}
}
启动go客户端http服务
$ go run main.go
HTTP请求go客户端
http://**.**.**.**:9090/