PHP (client) and Golang (server) use grpc + protobuf to communicate

  To explain from scratch, PHP (client) and Golang (server) use grpc + protobuf to communicate. Because my local environment is configured to prevent me from falling down, I developed in the docker environment and pulled Alpine的镜像。a security-oriented light Linux distribution based on the Alpine operating system  .

Build environment

1. In the project, I will use composer and PHP related extensions, so I pull a docker image based on PHP7.2. For the parameters in the command, see my other article, Docker Notes-Common Basic Commands .

docker container run -it --name grpc-ubuntu -v /Users/wuerzhilv-lq/examples:/home/examples lorisleiva/laravel-docker:7.2 /bin/bash

2. Install related packages

apk add autoconf automake libtool linux-headers  

3. This docker has no golang language environment, we install it here. Here by way of compiled and installed, why not install apk package manager, since there are pit 详情链接.

Go工具链是用Go编写的,要构建它,需要安装Go编译器;由于我们没有GO编译器,同时1.4以后的GO语言版本没有直接支持GCC,支持GO编译器GCCGO,因此我们需要先现在1.4版本的GO,利用GCC编译好GO编译器后,再利用1.4版本的GO编译器编译最新版本的GO(比如以下的1.14)。

  

①Download go1.4 version, the source code is 
wget https://dl.google.com/go/go1.4-bootstrap-20171003.tar.gz 
tar -zxf go1.4-bootstrap-20171003.tar.gz 
mv go /usr/local/go1.4 
②Download go1.14 version 
wget https://dl.google.com/go/go1.14.2.src.tar.gz 
tar -zxf go1.14.2.src.tar.gz 
mv go / usr / local / go 
③Environment variable setting (GOROOT_BOOTSTRAP is required for compiler environment setting) 
echo 'export GOROOT_BOOTSTRAP = / usr / local / go1.4' >> ~ / .bash_profile 
echo 'export GOROOT = / usr / local / go '>> ~ / .bash_profile 
echo' export PATH = $ {GOROOT} / bin: $ {PATH} '>> ~ / .bash_profile 
// Reload environment configuration variables (mainly overload GOROOT_BOOTSTRAP) source ~ /. bash_profile
 
④ compiled version of go1.4 
cd /usr/local/go1.4/src ./make.bash &&





⑤ use go1.4 the go compilers, compiler go1.14 cd / usr / local / go / src && ./make.bash ⑥View golang version go version

4. The newly downloaded php has no ready-made php.ini file. Just gave two suggestions for php.ini-development (for development environment) and php.ini-production (for production environment). Here we copy a php.ini file based on the production environment.

cp /usr/local/etc/php/php.ini-production  /usr/local/etc/php/php.ini

5.系统层面的,我们环境就安装好了。Grpc 是使用protobuf来传输数据,protobuf是一个文件,那怎么让php和golang语言识别它,这里就需要一个编译工具了。

apk add protobuf

6.? PHP installs Grpc, Protobuf extension.

pecl install grpc-1.25.0
pecl install protobuf-3.11.4

打开我们新建的php.ini文件,将扩展加进去。可以使用php -m 查看配置是否生效。

extension=grpc.so    extension=protobuf.so

7. Install PHP Protoc Plugin

$ git clone -b v1.28.1 https://github.com/grpc/grpc
$ cd grpc
$ git submodule update --init
$ make grpc_php_plugin
make编译后,输出目录为bins/opt,输出文件grpc_php_plugin,将文件复制到/home/examples
cp bins/opt/grpc_php_plugin  /home/examples/

8.安装Golang Protoc Plugin

go get -u github.com/golang/protobuf/protoc-gen-go
export PATH=$PATH:$GOPATH/bin

9. Install grpc

go get -u google.golang.org/grpc

10. The environment is ready, let's write the project code. When I created the docker container, I mounted the container directory locally, and I can use the ide tool to develop it.

  The local directory I configured here is / Users / wuerzhilv-lq / examples. Examples is equivalent to the project directory. In this project, a new protos directory is used to store protobuf files; a new php directory is used to store client code; and a new go directory is used to store server code.

 

      We create a new protobuf file (helloworld.proto ) to define service methods, request parameters, and request return values. The content is as follows

// Define the grammar. There are two types of proto2 and proto3. I use proto3 here. 
syntax = "proto3"; 

// Define the service (I feel like a class) 
service Greeter { 
  // Define the service method as SayHello, there can be multiple methods 
  rpc SayHello (HelloRequest) returns (HelloReply) {} 
} 

// Define the request parameter 
message HelloRequest { 
  string name = 1; 
} 

// Define the return parameter 
message HelloReply { 
   string message = 1; 
}

11. The server code, enter the project directory in the container, and use the proto tool to generate the server (golang) code to the go directory according to the protobuf file. After executing the command, a proto folder will appear in the go folder, which contains a helloworld.pb.go file.

protoc protos/helloworld.proto --go_out=plugins=grpc:go

    In the examples / go folder, create a new main.go file and register the helloworld service.

package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "./protos"
)

const (
    port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    log.Printf("Received: %v", in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, 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{})
    log.Printf("服务启动"+port)
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

   Run go run main.go to start the service and see if the service can be started.

12. Client code, enter the project directory in the container, use the proto tool to generate the client (PHP) code to the php directory according to the protobuf file. After executing the command, some files will appear in the php folder.

protoc --proto_path=protos   --php_out=php   --grpc_out=php   --plugin=protoc-gen-grpc=/home/examples/grpc_php_plugin protos/helloworld.proto

  Replace composer source

composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

  Through the composer tool, we initialize a composer.json file.

 composer.json内容如下:

{

  "name": "grpc/grpc-demo",
  "description": "gRPC example for PHP",
  "require": {
    "grpc/grpc": "^1.27",
    "google/protobuf": "^3.11"
  },
  "authors": [

    {

      "name": "Li",
      "email": "[email protected]"
    }
  ]
}

 composer install installs the extension package.  

 In the php directory, create a new client file, greeter_client.php

<? php 
require dirname ( __FILE__ ). '/ vendor / autoload.php' ; @ include_once dirname ( __FILE__ ). '/ helloworld / GreeterClient.php' ; @ include_once dirname ( __FILE__ ). '/ helloworld / HelloReply.php' ; @ include_once dirname ( __FILE__ ). '/ helloworld / HelloRequest.php' ; @ include_once dirname ( __FILE__ ). '/ GPBMetadata / Helloworld.php' ; function greet ( $ name ) { $client = new Helloworld\GreeterClient('localhost:50051', [ 'credentials' => Grpc\ChannelCredentials::createInsecure(), ]); $request = new Helloworld\HelloRequest(); $request->setName($name); list($reply, $status) = $client->SayHello($request)->wait(); $message = $reply->getMessage(); return $message; } $name = !empty($argv[1]) ? $argv[1] : 'world'; echo greet($name)."\n";

13. Enter the examples project directory,

Start the server 
go run go / main.go
execute the client
php php / greeter_client.php

  If helloworld is output, it is successful.

 

总结:
  这篇文章,只是简单粗略说了下,Grpc+protobuf的使用,比如针对protobuf文件,具体的内容没有说。以后,我会在写一篇针对protobuf文件详细讲解的文章。我懂得也不是太多,就是当自己做了一次总结。如有不对的地方,大家多提意见。我本机挂了代理,所以没有遇到墙的问题,如果被墙了,自行百度吧。
参考了如下资料:
https://developers.google.com/protocol-buffers
https://grpc.io/docs/quickstart
https://golang.org/doc/install/source
https://tkstorm.com/posts-list/programming/go/build-golang-from-source-on-alpine/



Guess you like

Origin www.cnblogs.com/jingying/p/12708670.html