PHP作为客户端中调用golangGRPC服务端

该文详细介绍了如何使用gRPC实现Go语言服务端和PHP客户端的通信。首先展示了服务端和客户端的目录结构,接着详细讲解了golang服务端的代码实现,然后在PHP客户端部分,包括执行命令生成proto文件,配置php_grpc扩展,创建HelloClient和HelloStub文件,以及composer.json的处理,并给出了调用代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、看示例

1、请求结果

​2、服务端目录结构

3、客户端目录结构

二、golang服务端

三、php客户端

1.执行命令生成php的proto相关文件

2.php支持grpc调用环境

 3.新建文件HelloClient.php和HelloStub.php

4.composer.json处理

5.执行调用代码

一、看示例

1、请求结果

2、服务端目录结构

-  25gRPC服务端.go
-  proto
   - helloworld.pb.go
   - helloworld.proto
   - helloworld_grpc.pb.go

3、客户端目录结构

二、golang服务端

在上篇文章实现一个简单的Go语言gRPC示例已有,不过多赘述

package main

import (
	"context"
	"google.golang.org/grpc"
	"log"
	"net"
	pb "project01/proto"
)

const (
	port = ":50051"
)

type server struct {
	*pb.UnimplementedGreeterServer
}

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{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

三、php客户端

1.执行命令生成php的proto相关文件

protoc --php_out=php   ./helloworld.proto

2.php支持grpc调用环境

安装php_grpc.dll扩展

下载地址 https://windows.php.net/downloads/pecl/releases/grpc/

在php.ini文件中添加grpc扩展配置:extension=grpc.so

 3.新建文件HelloClient.php和HelloStub.php

<?php
/**
 * Created by PhpStorm.
 * User: 17208
 * Date: 2021/7/22
 * Time: 13:50
 */

namespace Helloworld;

/**
 * The greeting service definition.
 */
class HelloClient extends \Grpc\BaseStub
{

    /**
     * @param string $hostname hostname
     * @param array $opts channel options
     * @param \Grpc\Channel $channel (optional) re-use channel object
     */
    public function __construct($hostname, $opts, $channel = null)
    {
        parent::__construct($hostname, $opts, $channel);
    }

    /**
     * 这里对应protobuf定义的服务
     * @param \Helloworld\HelloRequest $argument input argument
     * @param array $metadata metadata
     * @param array $options call options
     * @return \Grpc\UnaryCall
     */
    public function SayHello(\Helloworld\HelloRequest $argument, $metadata = [], $options = [])
    {
        return $this->_simpleRequest('/helloworld.Greeter/SayHello',
            $argument,
            ['\Helloworld\HelloReply', 'decode'],
            $metadata, $options);
    }
}

<?php
namespace Helloworld;

/**
 * The greeting service definition.
 */
class HelloStub {

    /**
     * 这里对应protobuf定义的服务
     * Sends a greeting
     * @param \Helloworld\HelloRequest $request client request
     * @param \Grpc\ServerContext $context server request context
     * @return \Helloworld\HelloReply for response data, null if if error occured
     *     initial metadata (if any) and status (if not ok) should be set to $context
     */
    public function SayHello(
        \Helloworld\HelloRequest $request,
        \Grpc\ServerContext $context
    ): ?\Helloworld\HelloReply {
        $context->setStatus(\Grpc\Status::unimplemented());
        return null;
    }

    /**
     * Get the method descriptors of the service for server registration
     *
     * @return array of \Grpc\MethodDescriptor for the service methods
     */
    public final function getMethodDescriptors(): array
    {
        return [
            '/helloworld.Greeter/SayHello' => new \Grpc\MethodDescriptor(
                $this,
                'SayHello',
                '\Helloworld\HelloRequest',
                \Grpc\MethodDescriptor::UNARY_CALL
            ),
        ];
    }

}

4.composer.json处理

{
  "name": "grpc-go-php",
  "require": {
    "grpc/grpc": "^v1.3.0",
    "google/protobuf": "^v3.3.0"
  },
  "autoload":{
    "psr-4":{
      "GPBMetadata\\":"GPBMetadata/",
      "Helloworld\\":"Helloworld/"
    }
  }
}

5.执行调用代码

<?php

namespace webapi\modules\test\controllers;

use Grpc\ChannelCredentials;
use Helloworld\HelloClient;
use Helloworld\HelloRequest;
use webapi\extensions\BaseController;
use const Grpc\STATUS_OK;

class GrpcController extends BaseController
{
    public function actionDemo()
    {
        $name = !empty($argv[1]) ? $argv[1] : 'world';
        $hostname = !empty($argv[2]) ? $argv[2] : 'localhost:50051';
        $this->greet($hostname, $name);
    }

    private function greet($hostname, $name)
    {
        // 初始化一个客户端实例
        $client = new HelloClient($hostname, [
            'credentials' => ChannelCredentials::createInsecure(),
        ]);
        // 初始化一个请求类
        $request = new HelloRequest();
        // 参数赋值
        $request->setName($name);
        // 请求服务
        list($response, $status) = $client->SayHello($request)->wait();
        // 响应处理
        if ($status->code !== STATUS_OK) {
            echo "ERROR: " . $status->code . ", " . $status->details . PHP_EOL;
            exit(1);
        }
        echo "客户端返回结果:" . PHP_EOL;
        echo $response->getMessage() . PHP_EOL;
        exit;
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值