PHP & Golang 关于Grpc 学习笔记

1 篇文章 0 订阅
1 篇文章 0 订阅

Grpc 入门介绍

gRPC 官方文档中文版_V1.0

安装教程

在Golang 下安装
go get google.golang.org/grpc v1.56.1 
go get google.golang.org/protobuf v1.30.0 
在PHP下安装grpc 扩展
  1. 使用composer 安装grpc和protobuf(推荐使用)。

    {
      "name": "root/work",
      "type": "composer-plugin",
      "autoload": {
        "psr-4": {
          "Root\\Work\\": "src/"
        }
      },
      "authors": [
        {
          "name": "wangxiaoyang"
        }
      ],
      "require": {
        "grpc/grpc": "^1.52",
        "google/protobuf": "^3.23"
      }
    }

  2. 安装php扩展(grpc.so,protobuf.so)

    pecl install grpc
    pecl install protobuf

  3. grpc_php_plugin 依赖安装(安装过程较慢)(用于生成客户端代码,可手动写客户端代码)

    git clone -b RELEASE_TAG_HERE https://github.com/grpc/grpc
    cd grpc
    git submodule update --init
    mkdir -p cmake/build
    cd cmake/build
    cmake ../..
    make protoc grpc_php_plugin

安装protobuf 代码编辑器

  1. Mac 下推荐使用 brew 安装。安装命令

    brew install protobuf

  2. Windows 下参考:https://zhuanlan.zhihu.com/p/361997082

  3. 安装完成后通过命令: protoc 检查是否成功

     

  4. 关于对protoc 的使用说明

    1. 在Golang 下编译命令

      protoc --proto_path=. --go_out=. proto/greeter/greeter.proto 
    2. PHP下编译命令

      protoc --proto_path=. --php_out=. proto/greeter/greeter.proto 
  5. 搜索参数路径

    1. 即 -IPATH,--proto_path=PATH ,表示要在哪个文件路径下搜索.proto 文件,既可以用-I 指定,也可以通过--proto_path= 指定路径。

    2. 当不指定路径时,默认当前路径, 也可以指定多个路径,在多个路径下搜索。

    3. 如下命令。含义相同

      protoc --go_out=. proto/greeter/greeter.proto
      
      #点号表示当前路径,注意-I参数没有等于号
      protoc -I. --go_out=. proto/greeter/greeter.proto 
      
      protoc --proto_path=. --go_out=. proto/greeter/greeter.proto 

  6. 语言插件路径

    1. 如: --cpp_out=, php_out= 等,若protoc 内置语言,则无需另外安装。内置语言如下:

     

  7. 若使用没有内置的语言,则需要单独安装插件。如:golang 的--go_out= , 对应的插件为:protoc-gen-go

    1. 安装命令如下

      # 最新版
      go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
      
      # 指定版本
      go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.3.0

  8. proto文件位置参数

    1. 即@<filename> 参数,指定了.proto 的文件具体位置, 如:

              /Users/yancy/project/go/src/grpc-client/hello/hello.proto

  9. Protobuf 语法规范

    https://www.topgoer.com/%E5%BE%AE%E6%9C%8D%E5%8A%A1/Protobuf%E8%AF%AD%E6%B3%95.html

    1. 见资料:Protobuf语法 · Go语言中文文档

Demo 

  1. 编写.proto 文件

    syntax = "proto3"; // 指定proto版本
    
    package hello;     // 指定默认包名// 指定golang包名
    option go_package = "./hello";// 定义Hello服务
    service Hello {
      // 定义SayHello方法
      rpc SayHello(HelloRequest) returns (HelloResponse) {}
    }
    // HelloRequest 请求结构
    message HelloRequest {
      string name = 1;
    }
    // HelloResponse 响应结构
    message HelloResponse {
      string message = 1;
      int64 code = 2;
    }

  2. 在golang下生成go文件

    protoc --go_out=./ --go_opt=paths=source_relative --go-grpc_out=./ --go-grpc_opt=paths=source_relative hello.proto

  3. 生成文件路径

  4. 编写gRpc服务端代码

    // Package server /**
    package main
    
    import (
       "context"
       "fmt"
       "google.golang.org/grpc"
       pb "grpc-client/hello"
       "log"
       "net"
    )
    
    const Port = ":50051"
    
    type server struct {
       pb.UnimplementedHelloServer
    }
    
    func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
       log.Printf("Received: %v\n", in.GetName())
       return &pb.HelloResponse{Message: "Hello, " + in.GetName()}, nil
    }
    
    func main() {
       listen, err := net.Listen("tcp", Port)
    
       if err != nil {
          log.Fatalf("failed to listen: %v", err)
       }
       s := grpc.NewServer()
       pb.RegisterHelloServer(s, &server{})
       fmt.Printf("Starting listen on port: %s", Port)
       if err := s.Serve(listen); err != nil {
          log.Fatalf("failed to serve: %v", err)
       }
    }

  5. 编写客户端代码

    1. Golang 客户端代码

      // Package client /**
      package main
      
      import (
         "golang.org/x/net/context"
         "google.golang.org/grpc"
         "google.golang.org/grpc/credentials/insecure"
         "google.golang.org/grpc/grpclog"
         pb "grpc-client/hello"
         "log"
      )
      
      const (
         Addr = "127.0.0.1:50051"
      )
      
      func main() {
         conn, err := grpc.Dial(Addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
         if err != nil {
            log.Fatalf("could not greet: %v", err)
         }
         defer conn.Close()
      
         // 初始化客户端
         c := pb.NewHelloClient(conn)
         // 调用方法
         req := &pb.HelloRequest{Name: "gRPC"}
         res, err := c.SayHello(context.Background(), req)
      
         if err != nil {
            grpclog.Fatalln(err)
         }
         log.Printf("Greeting: %s", res.GetMessage())
      }

    2. PHP 客户端代码

      <?php
      
      namespace Grpc\Client;
      
      use Grpc\BaseStub;
      use Grpc\Hello\HelloRequest;
      use Grpc\UnaryCall;
      
      class HelloClient extends BaseStub
      {
          /**
           * @throws \Exception
           */
          public function __construct($hostname, $opts, $channel = null)
          {
              parent::__construct($hostname, $opts, $channel);
          }
      
      
          public function sayHello(HelloRequest $argument, $metadata = [], $options = []): UnaryCall
          {
              return $this->_simpleRequest('Grpc.Hello.Hello/SayHello',
                  $argument,
                  ['Grpc\Hello\HelloResponse', 'decode'],
                  $metadata, $options);
          }
      
      }

  6. 测试

    1. PHP客户端接口测试代码

      public function helloRpcAction()
      {
      
          $hostname = "127.0.0.1:50051";
          try {
              $client = new HelloClient($hostname, [
                  'credentials' => ChannelCredentials::createInsecure(),
              ]);
              $request = new HelloRequest();
      
              $request->setName("phalcon");
      
              list($response, $status) = $client->SayHello($request)->wait();
              if ($status->code != STATUS_OK) {
                  ErrorHandler::setErrorInfo($status->code, $status->details);
                  return FALSE;
              }
              var_dump($response->getMessage());
              var_dump($response->getCode());
              var_dump($response->getData());
              die;
          } catch (\Exception $exception) {
              var_dump($exception->getMessage());
          }
      }

    2. 启用服务端

    3. 客户端调用

      1. golang客户端调用:

      2. php客户端调用:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 很高兴为您提供帮助!关于Go语言中的GRPC教程,您可以参考Go官方文档中的GRPC教程:https://grpc.io/docs/tutorials/basic/go/,也可以参考GitHub上的一些开源项目,如https://github.com/grpc/grpc-go。 ### 回答2: GolangGRPC教程是关于如何使用Google开发gRPC框架来构建高效的分布式系统的指南。GRPC是一种远程过程调用(RPC)框架,主要用于在客户端和服务器之间进行通信。 GolangGRPC教程首先介绍了GRPC的基本概念和原理,例如客户端和服务器之间的通信方式以及如何定义服务和消息。然后,教程详细介绍了如何在Golang中安装和配置GRPC的软件开发工具包,并提供了一些示例代码来说明如何创建GRPC服务器和客户端。 接下来,教程会教你如何使用protobuf(Protocol Buffers)作为GRPC的数据格式,protobuf是一种轻量级且语言无关的数据序列化机制。你将学会如何定义消息和服务接口,以及如何使用protobuf生成Golang的代码。 在教程的后半部分,你将学习如何使用GRPC的不同功能,如流式传输、服务器端流式和客户端流式,以及双向流式。这些功能可以让你更灵活地设计和实现你的分布式系统。 此外,教程还涉及了如何使用拦截器(interceptors)来实现自定义的认证、日志记录和错误处理等功能。你将了解如何在GRPC中实现服务端和客户端的拦截器,并掌握如何在应用程序中使用它们。 最后,教程还会介绍一些关于GRPC的最佳实践,例如如何处理错误、优化性能和处理并发等问题。这些实践可以帮助你在开发和维护GRPC应用程序时更高效和可靠。 总之,GolangGRPC教程提供了一种简单且强大的方式来构建分布式系统,并为你提供了充足的示例代码和实践经验来帮助你理解和应用GRPC框架。无论是初学者还是有经验的开发者,都能受益于这个教程。 ### 回答3: GolangGRPC教程是介绍Go语言中的GRPC框架的教程。GRPC是一种高性能、开源的远程过程调用(RPC)框架,支持多种编程语言,包括Go语言。 在GRPC教程中,首先会介绍GRPC的基本概念和架构。GRPC使用Protocol Buffers(简称Protobuf)作为接口定义语言(IDL),用于定义服务接口和消息格式。它提供了强类型的接口定义和支持多种语言的代码生成工具。通过IDL的定义,可以自动生成客户端和服务器端代码,大大简化了跨服务通信的开发工作。 接下来的教程将详细介绍如何使用GRPC构建客户端和服务器端。通过定义GRPC服务的接口和消息格式,可以方便地在不同的服务之间进行通信。教程会演示如何编写服务器端代码,实现服务接口的具体逻辑,并将其注册到GRPC框架中。同时,还会演示如何编写客户端代码,通过GRPC调用服务器端提供的服务,并处理返回的结果。 GRPC教程还会介绍一些高级特性,例如流式处理、认证和安全性等。流式处理支持客户端流、服务器端流和双向流,可以实现更复杂的通信模式。认证和安全性可以通过TLS/SSL等机制来保护通信的安全性。 在学习GRPC教程时,你将会了解到GRPC的优势和如何使用GRPC来构建可扩展和高性能的分布式系统。通过GRPC,你可以轻松地实现跨语言的服务调用,并利用其丰富的特性来满足不同的业务需求。 总之,GolangGRPC教程是一个很好的学习资源,能够帮助你掌握GRPC框架的基本概念和使用方法,并在实际项目中应用它来构建高效可靠的分布式系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值