zoukankan      html  css  js  c++  java
  • 通过gRPC让PHP调用Go的服务

    *由于篇幅限制,本文只能提供一个简单的使用流程,不会对具体的概念深入解释

    你至少需要了解的基本知识: PHP, Composer, Go, ProtoBuf, gRPC

    #第一步:编写 .proto 文件

    在本例中,我们定义一个计算器类,拥有相加,相减两个方法,以及定义参数和返回值的类型

    syntax = "proto3"; //使用的proto3语法版本
    package grpc_test; // 包名
    //定义一个服务,包含两个方法
    service Calculator {
        rpc Add (RequestData) returns (ResponseData) {}
        rpc Reduce (RequestData) returns (ResponseData) {}
    }
    // 定义一个请求类型
    message RequestData {
        int32 a = 1;
        int32 b = 2;
    }
    // 定义一个返回类型
    message ResponseData {
        int32 c = 1;
    }

    #使用protoc编译器编译 .proto 文件

    protoc -I ./proto 
        ./proto/grpc_test.proto 
        --php_out=./php_src 
        --go_out=plugins=grpc:./go_src 
        --grpc_out=./php_src 
        --plugin=protoc-gen-grpc=/opt/share/grpc_php_plug

    说明:
    1 指定.proto文件目录
    2 指定.proto文件位置
    3 根据proto文件定义生成对应php代码
    4 根据proto文件定义生成对应的go代码
    5 输出grpc的php调用客户端代码
    6 grpc_php_plugin插件位置(这个需要下载源代码编译得出)

    该命令执行后,会在go_src下生成相关的go代码,php_src下生成对应的php代码

    #利用生成的go代码编写gRPC服务

    package main
    
    import (
        "context"
        "fmt"
        "google.golang.org/grpc"
        pb "grpc_test/go_src" //引入了生成的go代码
        "log"
        "net"
    )
    
    func main() {
        lis, err := net.Listen("tcp", "192.168.0.220:8888")
        if err != nil {
            log.Fatalf("failed to listen: %v", err)
        }
        s := grpc.NewServer()
        pb.RegisterCalculatorServer(s, &server{})
        if err := s.Serve(lis); err != nil {
            log.Fatalf("failed to serve: %v", err)
        }
    }
    
    type server struct {
        pb.UnimplementedCalculatorServer
    }
    
    func (s *server) Add(ctx context.Context, in *pb.RequestData) (*pb.ResponseData, error) {
        fmt.Println("add:")
        return &pb.ResponseData{
            C: in.A + in.B,
        }, nil
    }
    func (s *server) Reduce(ctx context.Context, in *pb.RequestData) (*pb.ResponseData, error) {
        fmt.Println("reduce:")
        return &pb.ResponseData{
            C: in.A - in.B,
        }, nil
    }

    #编译并运行代码,服务就开始监听了

    #准备PHP环境
    这一部分稍微就麻烦点,需要安装两个扩展grpc,protobuf 可以通过pecl安装:

    pecl install grpc
    pecl install protobuf
    安装后在对应的php.ini文件中添加
    extension=grpc.so
    extension=protobuf.so

    将ptotoc编译生成的php代码添加到composer.json中
    "psr-4": {
    "GPBMetadata\":"app/grpc/GPBMetadata/",
    "Grpc_test\":"app/grpc/Grpc_test/"
    },

    #编写PHP客户端调用代码

    namespace Appgrpc;
    
    use GrpcChannelCredentials;
    use Grpc_testCalculatorClient;
    use Grpc_testRequestData;
    
    class Grpctest
    {
        public function add() {
            $ins = new CalculatorClient("192.168.0.220:8888",[
                'credentials' => ChannelCredentials::createInsecure()
            ]);
            $req = new RequestData();
            $req->setA(40);
            $req->setB(20);
            list($res, $status) = $ins->Reduce($req)->wait();
            dd($res->getC());
        }
    }

    如果一切顺利,这里应该打印出最终结果 20

    #最后梳理一下整个流程

    1.首先编写proto文件
    2.生成对应的服务端和客户端辅助代码
    3.借助辅助代码编写服务端和客户端

  • 相关阅读:
    将现有MySQL数据库改为大小写不敏感
    在Windows中玩转Docker Toolbox
    使用ABP EntityFramework连接MySQL数据库
    数据库设计范式2——BC范式和第四范式
    让OData和NHibernate结合进行动态查询
    文档在线预览的实现
    有哪些老鸟程序员知道而新手不知道的小技巧?自我感受
    EEPROM的概念接口类型及软件实例
    flash的几种模式Normal Mode、DUAL Mode、Quad Mode的概念和区别
    ESP8266 打造一款物联网产品---搭建环境编译及烧录
  • 原文地址:https://www.cnblogs.com/codeAB/p/12212404.html
Copyright © 2011-2022 走看看