gRPC 客户端-服务器通信:一站式学习指南

admin 2024-01-30 68 阅读 0评论

在随着软件开发领域的不断发展,客户端与服务器之间的高效通信至关重要。gRPC 作为一种高性能开源框架,能够促进跨各种编程语言的无缝且强大的通信。本系列文章将深入探讨使用gRPC搭建客户端-服务器架构的复杂性,并重点关注 PHP 和 Go 语言的应用。

PHP gRPC 客户端配置

本指南将带领您逐步使用 PHP 配置 gRPC 客户端。我们将涵盖从设置项目结构和创建 proto 文件到对环境进行 Docker 化以及编写 PHP gRPC 客户端代码的各个步骤。每个步骤都将进行详细解释,确保您能够轻松理解并完成配置。完成本指南后,您将拥有一个功能完整的 PHP gRPC 客户端,可以与服务器进行通信。

探索要点:

  • 初始文件夹结构
  • 创建proto文件
  • 创建Composer文件
  • Composer 自动加载配置
  • Composer安装脚本
  • PHP 的 Dockerfile 设置
  • PHP gRPC 客户端代码
  • Docker Compose 配置

1. 初始文件夹结构

确保项目具有以下目录结构:

|-php-grpc
    |- docker
    |  |- php
    |  |   |- Dockerfile
    |  |   |- install-composer.sh
    |  |- go
    |  |   |- Dockerfile
    |  |- docker-compose.yml  
    |- grpc-client-php
    |     |- composer.json
    |     |- src
    |     |   |- user.php
    |- grpc-server-go
    |     |- main.go
    |- protos
          |- userService.proto

2. 创建proto文件

创建protos/serService.proto并包含以下内容的文件:

// 用户服务定义
service User {
  //发送问候语
  rpc FindById (FindByIdRequest) returns (FindByIdReply) {}
}

//包含用户 ID 的请求消息
message FindByIdRequest {
  string id= 1;
}

// 包含用户消息的响应消息
message FindByIdReply {
  string id = 1;
  string name = 2;
}

在docker镜像构建过程中编译userService.proto文件后,创建两个文件夹./grpc-client-php/src/GPBMetadata ,./grpc-client-php/src/Grpc其结构如下:

    app
    |- grpc-client-php
    |- GPBMetadata
    |    |- UserService.php
    |- Grpc
    |    |- FindByIdReply.php
    |    |- FindByIdRequest.php
    |    |- UserClient.php

3. 创建Composer文件

{
    "name""php/grpc",
    "description""grpc example",
    "type""project",
    "require": {
        "grpc/grpc""^1.57",
        "google/protobuf""^4.0@RC"
    },
    "license""Free"
}

4.Composer自动加载配置

composer.json位于 的文件中./grpc-client-php/composer.json,添加以下内容:

{
  ...,
    "autoload": {
        "psr-4": {
            "Grpc\\""src/Grpc",
            "GPBMetadata\\""src/GPBMetadata"
        }
    }
}

5.Composer安装脚本

Composer 将在创建 docker 镜像时安装,下面的sh脚本下载并安装composer

./docker/php/install-composer.sh创建包含以下内容的文件


#!/bin/sh
echo 'It is being installed a COMPOSER'
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "
$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
then
    >&2 echo 'ERROR: Invalid installer checksum'
    rm composer-setup.php
    exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php

mv composer.phar /usr/local/bin/composer
exit $RESULT

6. PHP 的 Dockerfile

./docker/php/Dockerfile创建包含以下内容的文件

FROM php:8.3-fpm-alpine

COPY docker/php/install-composer.sh /tmp
RUN chmod +x /tmp/install-composer.sh && sh /tmp/install-composer.sh

COPY ./grpc-client-php /app/grpc-client-php
COPY ./protos /app/protos

RUN apk add --update linux-headers \
   && apk add --no-cache autoconf gcc make g++ zlib-dev git cmake \
   && pecl channel-update pecl.php.net \
   # Install the grpc extension
   && pecl install grpc \
   && docker-php-ext-enable grpc

# INstall gRPC PHP plugin
RUN cd /app && git clone https://github.com/grpc/grpc \
   && cd /app/grpc && git submodule update --init \
   && mkdir -p cmake/build && cd cmake/build && cmake ../.. && make protoc grpc_php_plugin

RUN cd /app/grpc-client-php \
   #Install required packages
   && composer install \
   # install protobuf compiler
   && apk add protobuf \
   # Compile userService.proto file
   && cd /app && protoc --proto_path=protos \
   --php_out=./grpc-client-php/src \
   --grpc_out=./grpc-client-php/src \
   --plugin=protoc-gen-grpc=./grpc/cmake/build/grpc_php_plugin \
   ./protos/userService.proto

WORKDIR /app

CMD ["php-fpm"]

7. PHP gRPC 客户端代码

grpc-client-php/src/user.php创建包含以下内容的文件:

<?php

use Grpc\UserClient;
use Grpc\ChannelCredentials;
use Grpc\FindByIdRequest;

require dirname(__FILE__) . '/../vendor/autoload.php';

/**
 * 解析 GRPC 错误
 */
function getErrorMessage(\stdClass $status, string $id): string
{
    if ($status->code !== \Grpc\STATUS_NOT_FOUND)
        return sprintf("User %s was not found"$id);

    return "ERROR: " . $status->code . ", " . $status->details;
}

function run(string $hostname, string $id): void
{
    // 创建 grpc 客户端
    $userClient = new UserClient($hostname, [
        'credentials' => ChannelCredentials::createInsecure(),
    ]);

    // 创建 grpc 请求
    $request = new FindByIdRequest();
    $request->setId($id);


    // 调用 FindById 远程过程
    list($response$status) = $userClient->FindById($request)->wait();

    // 如果出现错误,显示错误并退出
    if ($status->code !== \Grpc\STATUS_OK) {
        echo getErrorMessage($status$id) . PHP_EOL;
        exit(1);
    }

    // 显示收到的用户名
    echo $response->getName() . PHP_EOL;
}

// 想要用户 ID 
$id = !empty($argv[1]) ? $argv[1] : 'some-unique-id';

// grpc服务器地址
$hostname = !empty($argv[2]) ? $argv[2] : 'grpc-server:9090';


run($hostname$id);

8.Docker 组合

创建docker/docker-compose.yml文件:

version: '3.6'
services:
  grpc-client:
    build:
      context: ../
      dockerfile: docker/php/Dockerfile
    container_name: grpc-client
    volumes:
      - ../grpc-client-php:/project
    networks:
      - dev_grpc_network

networks:
  dev_grpc_network:
      external: true

9. 构建并运行

创建 Docker 网络:

docker network create dev_grpc_network

构建并运行 gRPC 客户端容器:

cd ./docker 
docker compose up --build grpc-client -d

发表评论

快捷回复: 表情:
Addoil Applause Badlaugh Bomb Coffee Fabulous Facepalm Feces Frown Heyha Insidious KeepFighting NoProb PigHead Shocked Sinistersmile Slap Social Sweat Tolaugh Watermelon Witty Wow Yeah Yellowdog
提交
评论列表 (有 0 条评论, 68人围观)
0.202754s