美文网首页PHP经验分享码农的世界程序员
mac下grpc(golang server + php cli

mac下grpc(golang server + php cli

作者: 陈晓风 | 来源:发表于2018-07-01 22:42 被阅读43次

    目前微服务这么流行,RPC框架也是百花齐放,本文讲述一下mac下grpc的开发环境搭建,其中server端使用golang,客户端使用php。

    服务端

    golang grpc安装

    这里列出了一个参考,由于grpc在github上的文件目录有改动,所以直接按官方的安装,会出404资源无法找到的问题。
    需要先在本地安装golang+grpc。具体可参考:golang安装grpc
    操作完之后,在终端运行:protoc --version,能看到版本信息
    同时,protoc-gen-go命令应该也已经被安装

    查看protoc版本信息

    php grpc客户端

    扩展有几个,推荐使用官方的
    当然,另外一个也相当不错,datto的protobuf扩展。使用datto的这个的时候,我用perl根据其文档安装失败,既然官方的ok了,也就懒得再去折腾了。
    官方的具体的安装流程,刚刚给的github的网址上有详细的说明,根据步骤走,就ok了。
    安装完之后,为了在nginx下使用,应该装grpc这个扩展:

    php的grpc扩展安装成功查看

    开始Demo

    官方给了一个helloworld.proto的demo,咱们按样子,增加一个,目录结构如下: demo目录结构

    app和meta,放的是protoc编译之后的服务端的go的源码。
    grpc,将protoc编译成PHP所需要的工具及源码(即:grpc_php_plugin)
    phpClient,是protoc编译出来的php的源码,下面的vendor文件夹是composer加载的grpc/grpc的php客户端的连接服务端的源码

    上源码

    先建立文件夹:mkdir grpc_demo

    meta.proto的源码

    syntax = "proto3";
    
    package meta;
    
    service Agent {
      rpc GetInfo (MetaRequest) returns (MetaResponse);
    }
    
    message MetaRequest {
      string appId = 1;
    }
    
    message MetaResponse {
      string appId = 1;
      string title = 2;
      string name = 3;
      string logo = 4;
    }
    

    编译成golang文件:

    protoc --go_out=plugins=grpc:./meta ./meta.proto
    

    编译成php文件:

    protoc --proto_path=./ \
           --php_out=phpClient/meta \
           --grpc_out=phpClient/meta \
           --plugin=protoc-gen-grpc=./grpc/bins/opt/grpc_php_plugin \
           meta.proto
    

    编写main.go文件:(此处把helloworld.proto这个demo也加进来了)

    package main
    
    import (
        "log"
        "net"
        pb "grpc_demo/app"
        meta "grpc_demo/meta"
        "golang.org/x/net/context"
        "google.golang.org/grpc"
    )
    
    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 + "--from jacky_chen"}, nil
    }
    
    func (s *server) GetInfo(ctx context.Context, in *meta.MetaRequest) (*meta.MetaResponse, error) {
        return &meta.MetaResponse {
            AppId: in.AppId,
            Title: "my title",
            Name: "My Name",
            Logo: "https://xxx.com",
        }, 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{})
        meta.RegisterAgentServer(s, &server{})
        s.Serve(lis)
    }
    

    agent_client.php源码:

    <?php
    
    require dirname(__FILE__).'/../vendor/autoload.php';
    
    print_r(get_declared_classes());exit;
    
    include_once dirname(__FILE__).'/Meta/AgentClient.php';
    include_once dirname(__FILE__).'/Meta/MetaRequest.php';
    include_once dirname(__FILE__).'/Meta/MetaResponse.php';
    include_once dirname(__FILE__).'/GPBMetadata/Meta.php';
    $appId = "123";
    try {
        $client = new Meta\AgentClient('localhost:50051', [
            'credentials' => Grpc\ChannelCredentials::createInsecure(),
        ]);
        $request = new Meta\MetaRequest();
        $request->setAppId($appId);
        list($reply, $status) = $client->GetInfo($request)->wait();
        echo $reply->serializeToJsonString();
    } catch (\Throwable | \Error | \Exception $e) {
        echo  "error : " . $e->getMessage();
    }
    

    运行服务端:

    go run main.go
    

    运行客户端:

    php 
    

    结果如图:


    php调用go的rpc服务

    由于php本身的原因(官方是基于php-fpm,非常驻内存),所以grpc官方并没有php的服务端。当然,基于swoole开发的grpc的服务端在github上已经有了。

    相关文章

      网友评论

        本文标题:mac下grpc(golang server + php cli

        本文链接:https://www.haomeiwen.com/subject/obrhuftx.html