目录
3.新建文件HelloClient.php和HelloStub.php
一、看示例
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;
}
}