3

我可以使用 python 客户端和服务器进行通信,但与 php 客户端混淆。我对 protobufers 感到困惑,一个解释整个过程的小程序会非常有帮助。

我浏览了许多文档,但仍然对实际流程感到非常困惑。

计算器.proto

syntax = "proto3";

message Request {
    int32 num1 = 1;
    int32 num2 = 2;
}

message Response{
    int32 result = 1;
}

service Calculator {
    rpc Sum(Request) returns (Response) {}
}

计算器.py

def sum(x1,x2):
  y= x1+x2
  return y

服务器.py

import grpc
from concurrent import futures
import time

# import the generated classes
import calculator_pb2
import calculator_pb2_grpc

# import the original calculator.py
import calculator

# create a class to define the server functions, derived from
# calculator_pb2_grpc.CalculatorServicer
class CalculatorServicer(calculator_pb2_grpc.CalculatorServicer):

    # calculator.sum is exposed here
    def Sum(self, request, context):
        response = calculator_pb2.Response()
        response.result = calculator.sum(request.num1,request.num2)
        print 'Result:',response.result
        return response


# create a gRPC server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

# use the generated function `add_CalculatorServicer_to_server`
# to add the defined class to the server
calculator_pb2_grpc.add_CalculatorServicer_to_server(
        CalculatorServicer(), server)

# listen on port 50051
print('Starting server. Listening on port 50051.')
server.add_insecure_port('[::]:50051')
server.start()

# since server.start() will not block,
# a sleep-loop is added to keep alive
try:
    while True:
        time.sleep(86400)
except KeyboardInterrupt:
    server.stop(0)

客户端.py

import grpc

# import the generated classes
import calculator_pb2
import calculator_pb2_grpc

# open a gRPC channel
channel = grpc.insecure_channel('localhost:50051')

# create a stub (client)
stub = calculator_pb2_grpc.CalculatorStub(channel)
while True:
    try:
        # create a valid request message
        numbers = calculator_pb2.Request(num1=int(input("Enter number1: ")),num2=int(input("Enter number2: ")))
    # make the call
        response = stub.Sum(numbers)

        # print 'Result:',response.result
    except KeyboardInterrupt:
        print("KeyboardInterrupt")
        channel.unsubscribe(close)
        exit()

此设置在服务器(python)中返回两个数字的加法。我想要与 python 作为服务器和 php 作为客户端的相同功能。

4

1 回答 1

3

我可以与 php 客户端和 python 服务器进行通信。以下是步骤和示例:

脚步:


--------------------------------
           Python
--------------------------------

1. Make a folder named grpc

2. Install pip for python

3.Install virtual environment
  python -m pip install virtualenv

4. Run the commands
   virtualenv venv
   source venv/bin/activate
   python -m pip install --upgrade pip

5. Then install grpcio
   python -m pip install grpcio

6. Install grpc tools
   python -m pip install grpcio-tools

7. Generate protobuf
   python -m grpc_tools.protoc -I./proto --python_out=. --grpc_python_out=. ./proto/calculator.proto 

8. Make server.py


---------------------------------
           PHP
---------------------------------

1. Install composer
   composer install

2. Run these commands to install grpc using pecl
   sudo apt-get install php-dev
   pecl
   sudo pecl install grpc

3. Download protoc version > 3.7
commands:
PROTOC_ZIP=protoc-3.7.1-linux-x86_64.zip
curl -OL   https://github.com/protocolbuffers/protobuf/releases/download/v3.7.1/$PROTOC_ZIP
sudo unzip -o $PROTOC_ZIP -d /usr/local bin/protoc
sudo unzip -o $PROTOC_ZIP -d /usr/local 'include/*'
rm -f $PROTOC_ZIP  

4. Clone this repo
   git clone -b v1.27.0 https://github.com/grpc/grpc


5. Run this command
   cd grpc && git submodule update --init && make grpc_php_plugin
   cd examples/php/route_guide
   ./route_guide_proto_gen.sh

6. Move to root then run: make grpc_php_plugin

7.Generate protobuf
   protoc --proto_path=examples/protos --php_out=examples/php/route_guide --grpc_out=examples/php/route_guide --plugin=protoc-gen-grpc=bins/opt/grpc_php_plugin ./examples/protos/calculator.proto

8. Make index.php

索引.php


<?php

include __DIR__ . '/vendor/autoload.php';
include __DIR__ . '/grpc/examples/php/route_guide/Calculator/CalculatorClient.php';
include __DIR__ . '/grpc/examples/php/route_guide/Calculator/SumRequest.php';
include __DIR__ . '/grpc/examples/php/route_guide/Calculator/SumResponse.php';
include __DIR__ . '/grpc/examples/php/route_guide/GPBMetadata/Calculator.php';

function add()
{
    // Listening to port
    $client = new \Calculator\CalculatorClient('localhost:6000', [
        'credentials' => Grpc\ChannelCredentials::createInsecure(),
    ]);
    while (true) {
        try {
            // request object
            $request = new \Calculator\SumRequest();
            echo " Num1: ";
            // num1
            $request->setNum1((int) rtrim(fgets(STDIN)));
            echo " Num2: ";
            // num2
            $request->setNum2((int) rtrim(fgets(STDIN)));

            list($res, $status) = $client->Sum($request)->wait();
            // result
            echo $res->getResult() . "\n";

        } catch (Exception $error) {
            echo $error;
        }
    }
}

try {
    add();
    //    phpinfo();
} catch (Exception $e) {
    echo $e;
}

计算器.py


def sum(x1,x2):
  y= x1+x2
  return y

服务器.py

import grpc
from concurrent import futures
import time

# import the generated classes
import calculator_pb2
import calculator_pb2_grpc

# import the original calculator.py
import calculator

# create a class to define the server functions, derived from
# calculator_pb2_grpc.CalculatorServicer
class CalculatorServicer(calculator_pb2_grpc.CalculatorServicer):

    # calculator.sum is exposed here
    def Sum(self, request, context):
        response = calculator_pb2.SumResponse()
        response.result = calculator.sum(request.num1,request.num2)
        print 'Result:',response.result
        return response


# create a gRPC server
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))

# use the generated function `add_CalculatorServicer_to_server`
# to add the defined class to the server
calculator_pb2_grpc.add_CalculatorServicer_to_server(
        CalculatorServicer(), server)

# listen on port 50051
print('Starting server. Listening on port 6000.')
server.add_insecure_port('[::]:6000')
server.start()

# since server.start() will not block,
# a sleep-loop is added to keep alive
try:
    while True:
        time.sleep(86400)
except KeyboardInterrupt:
    server.stop(0)

计算器.proto



syntax = "proto3";

package Calculator;
message SumRequest {
    int64 num1 = 1;
    int64 num2 = 2;
}

message SumResponse{
    int64 result = 1;
}

service Calculator {
    rpc Sum(SumRequest) returns (SumResponse) {}
}

还可以通过这些链接更好地理解:PHP - https://grpc.io/docs/tutorials/basic/php/ Python - https://grpc.io/docs/tutorials/basic/python/

于 2020-03-03T17:12:07.427 回答