当前位置:网站首页 > 服务器 > 正文

CentOS下grpc的go服务端+PHP客户端实现

adminadmin 2019-01-08 344 0


首先声明,截至文章日期为止,并没有发布php的grpc服务端(据说是因为php不是常驻内存的原因),所以使用golang的服务端代替,反正不影响使用就行,另外如果你喜欢其他语言也可以,例如node做server。


一、首先安装golang并设置环境变量


安装方法看《CentOS安装/更新Golang 1.9以上版本》,最好安装1.9及以上的版本,然后设置变量,如下:

vi /etc/bashrc
export GOPATH=/home/Go
export GOROOT=/home/go
export PATH=$PATH:$GOROOT/bin
source /etc/bashrc


创建GOHOME目录

mkdir /home/Go


二、安装golang grpc


golang protobuf 库

go get -u github.com/golang/protobuf/proto

protoc --go_out 工具

go get -u github.com/golang/protobuf/protoc-gen-go


if (可以翻墙直接一句代码) {

      go get google.golang.org/grpc

}

else {

    mkdir -p $GOPATH/src/golang.org/x
    cd $GOPATH/src/golang.org/x
    git clone https://github.com/golang/net.git --depth 1
    git clone https://github.com/golang/text.git --depth 1
    git clone https://github.com/golang/sys.git --depth 1


    建立相关目录,进入目录

    mkdir -p $GOPATH/src/google.golang.org/
    cd $GOPATH/src/google.golang.org
    git clone https://github.com/google/go-genproto.git genproto --depth 1


    从Github上克隆grpc仓库

    git clone https://github.com/grpc/grpc-go.git grpc


    安装仓库

    cd $GOPATH/src/
    go install google.golang.org/grpc

}


三、运行go grpc


运行go grpc服务端和客户端 

1、服务端

编译服务端

cd $GOPATH/src/google.golang.org/grpc/examples/helloworld/greeter_server

go build -o greeter_server main.go

运行服务端

./greeter_server &



2、客户端

编译客户端

cd  $GOPATH/src/google.golang.org/grpc/examples/helloworld/greeter_client

go build -o greeter_client  main.go

运行客

./greeter_client 


出现如下信息证明成功

2019/01/08 18:18:54 Greeting: Hello world


四、安装php grpc客户端


php安装grpc扩展


五、创建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;
}


生成相关包文件

protoc --proto_path=/var/www/html/mysite --php_out=/var/www/html/mysite --grpc_out=/var/www/html/mysite --plugin=protoc-gen-grpc=/var/www/html/grpc/bins/opt/grpc_php_plugin /var/www/html/mysite/helloworld.proto

此时目录下会生成 GPBMetadata 和 Helloworld 两个目录



六、创建composer文件


创建composer.json文件,内容如下:

{
  "name": "grpc/grpc-demo",
  "description": "gRPC example for PHP",
  "require": {
    "grpc/grpc": "^v1.3.0",
    "google/protobuf": "^v3.3.0"
  },
  "autoload": {
    "psr-4": {
      "GPBMetadata\\": "GPBMetadata/",
      "Helloworld\\": "Helloworld/"
    }
  }
}


生成自动加载及公共类库vendor

composer install

注意:因为在composer.json里面已经指定了GPBMetadata、Helloworld的加载为止,所以composer install或者composer update之后不用单独包含这两个目录里面的类文件了,因为已经autoload自动加载。


七、php客户端调用


例子 1:

<?php
require dirname(__FILE__). '/vendor/autoload.php';
// 50051端口随意是什么都可以,不过要与服务端监听的端口一致
$client = new Helloworld\GreeterClient('127.0.0.1:50051', [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
$request = new Helloworld\HelloRequest();
$request->setName('hahahaha');
list($reply, $status) = $client->SayHello($request)->wait();
echo $reply->getMessage();exit;

例子2:

proto文件

syntax = "proto3";
package helloworld;
// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// 接收提交的参数
message HelloRequest {
    string id = 1;
    string name = 2;
}
// 为下面返回数据定义详细的格式
message Result {
    int32 id = 1;
    int32 age = 2;
    int32 gender = 3;
    string name = 4;
}
// 返回的数据
message HelloReply {
  repeated Result result = 1;
}

php客户端代码

<?php
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
require dirname(__FILE__). '/vendor/autoload.php';
// 需要返回的数据
$result = array(
    array (
        'id' => 1,
        'age' => 22,
        'gender' => 1,
        'name' => 'zhangsan'
    ),
    array (
        'id' => 2,
        'age' => 27,
        'gender' => 2,
        'name' => 'lijing'
    )
);
// 打开gRPC端口
$client = new Helloworld\GreeterClient('127.0.0.1:50051', [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);
// proto使用repeated类型数据格式,那么需要这个类,repeated类型数据格式主要是适用与重复出现的数据,例如N个用户的列表
$arr = new RepeatedField(GPBType::MESSAGE, Helloworld\Result::class);
// 这个是我自己定义的,为了偷懒,并不一定适用所有情景,你也可以使用SetXxx()、GetXxx()来代替
function func($key, $type = 'set')
{
    $key = explode('_', $key);
    $key = implode('', array_map('ucfirst', $key));
    return $type . ucfirst($key);
}
foreach ($result as $info) {
    $res = new \Helloworld\Result();
    foreach ($info as $key => $val) {
        $func = func($key, 'set');
        $res->$func($val);
    }
    $arr[] = $res;
}
$request = new \Helloworld\HelloRequest();
$request->setId(1);
$request->setName('zhangsan');
list($reply, $status) = $client->SayHello($request)->wait();
// 提交给服务端
$reply->setResult($arr);
if (is_object($reply) && $status->code == 0) {
    $list = array();
    foreach ($reply->getResult() as $val) {
        $info = array();
        foreach (array_keys($result[0]) as $key) {
            $func = func($key, 'get');
            $info[$key] = $val->$func();
        }
        $list[] = $info;
    }
    echo '<pre>';print_r($list);exit;
}
else {
    echo $status->details;
}



标签:grpcgo服务端php客户端

  • 流泪

    0

  • 打酱油

    0

  • 开心

    0

  • 鼓掌

    0

  • 恐怖

    1

猜你喜欢

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

请填写验证码
搜索
最近发表
标签列表
最新留言
    • 订阅本站的 RSS 2.0 新闻聚合