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

admin 2024-01-30 624 阅读 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
喜欢就支持以下吧
点赞 0

发表评论

快捷回复: 表情:
aoman baiyan bishi bizui cahan ciya dabing daku deyi doge fadai fanu fendou ganga guzhang haixiu hanxiao zuohengheng zhuakuang zhouma zhemo zhayanjian zaijian yun youhengheng yiwen yinxian xu xieyanxiao xiaoku xiaojiujie xia wunai wozuimei weixiao weiqu tuosai tu touxiao tiaopi shui se saorao qiudale qinqin qiaoda piezui penxue nanguo liulei liuhan lenghan leiben kun kuaikule ku koubi kelian keai jingya jingxi jingkong jie huaixiao haqian aini OK qiang quantou shengli woshou gouyin baoquan aixin bangbangtang xiaoyanger xigua hexie pijiu lanqiu juhua hecai haobang caidao baojin chi dan kulou shuai shouqiang yangtuo youling
提交
评论列表 (有 0 条评论, 624人围观)

最近发表

热门文章

最新留言

热门推荐

标签列表