PHP: php server commit 4/n, add RpcServer, generator and server examples (#25640)

* add RpcServer and generator
add server examples: greeter and route guide

* php server generator xds client

* add generated stub

* fix clang format fail
reviewable/pr26132/r1
Hannah Shi 4 years ago committed by GitHub
parent 7977494d02
commit 6769ce39f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. BIN
      examples/php/GPBMetadata/Helloworld.php
  2. 50
      examples/php/Helloworld/GreeterClient.php
  3. 58
      examples/php/Helloworld/GreeterStub.php
  4. 60
      examples/php/Helloworld/HelloReply.php
  5. 60
      examples/php/Helloworld/HelloRequest.php
  6. 4
      examples/php/composer.json
  7. 4
      examples/php/echo/composer.json
  8. 47
      examples/php/greeter_and_routeguide_multi_server.php
  9. 14
      examples/php/greeter_proto_gen.sh
  10. 44
      examples/php/greeter_server.php
  11. BIN
      examples/php/route_guide/GPBMetadata/RouteGuide.php
  12. 182
      examples/php/route_guide/RouteGuideService.php
  13. 112
      examples/php/route_guide/Routeguide/Feature.php
  14. 90
      examples/php/route_guide/Routeguide/Point.php
  15. 122
      examples/php/route_guide/Routeguide/Rectangle.php
  16. 105
      examples/php/route_guide/Routeguide/RouteGuideClient.php
  17. 139
      examples/php/route_guide/Routeguide/RouteGuideStub.php
  18. 111
      examples/php/route_guide/Routeguide/RouteNote.php
  19. 172
      examples/php/route_guide/Routeguide/RouteSummary.php
  20. 601
      examples/php/route_guide/route_guide_db.json
  21. 14
      examples/php/route_guide/route_guide_proto_gen.sh
  22. 34
      examples/php/route_guide/route_guide_server.php
  23. 183
      src/compiler/php_generator.cc
  24. 3
      src/compiler/php_generator.h
  25. 12
      src/compiler/php_generator_helpers.h
  26. 35
      src/compiler/php_plugin.cc
  27. 11
      src/php/bin/generate_proto_php.sh
  28. 205
      src/php/lib/Grpc/RpcServer.php
  29. 28
      src/php/lib/Grpc/ServerCallWriter.php
  30. 22
      src/php/lib/Grpc/ServerContext.php
  31. 80
      src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php
  32. 80
      src/php/tests/interop/Grpc/Testing/ReconnectServiceStub.php
  33. 222
      src/php/tests/interop/Grpc/Testing/TestServiceStub.php
  34. 62
      src/php/tests/interop/Grpc/Testing/UnimplementedServiceStub.php
  35. 59
      src/php/tests/interop/Grpc/Testing/XdsUpdateClientConfigureServiceStub.php
  36. 80
      src/php/tests/interop/Grpc/Testing/XdsUpdateHealthServiceStub.php
  37. 16
      src/php/tests/interop/xds_client.php
  38. 85
      src/php/tests/unit_tests/RpcServerTest.php
  39. 77
      src/php/tests/unit_tests/ServerCallTest.php

@ -0,0 +1,50 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace Helloworld;
/**
* The greeting service definition.
*/
class GreeterClient 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);
}
/**
* Sends a greeting
* @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);
}
}

@ -0,0 +1,58 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace Helloworld;
/**
* The greeting service definition.
*/
class GreeterStub {
/**
* 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
),
];
}
}

@ -0,0 +1,60 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
namespace Helloworld;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* The response message containing the greetings
*
* Generated from protobuf message <code>helloworld.HelloReply</code>
*/
class HelloReply extends \Google\Protobuf\Internal\Message
{
/**
* Generated from protobuf field <code>string message = 1;</code>
*/
protected $message = '';
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type string $message
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\Helloworld::initOnce();
parent::__construct($data);
}
/**
* Generated from protobuf field <code>string message = 1;</code>
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* Generated from protobuf field <code>string message = 1;</code>
* @param string $var
* @return $this
*/
public function setMessage($var)
{
GPBUtil::checkString($var, True);
$this->message = $var;
return $this;
}
}

@ -0,0 +1,60 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: helloworld.proto
namespace Helloworld;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* The request message containing the user's name.
*
* Generated from protobuf message <code>helloworld.HelloRequest</code>
*/
class HelloRequest extends \Google\Protobuf\Internal\Message
{
/**
* Generated from protobuf field <code>string name = 1;</code>
*/
protected $name = '';
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type string $name
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\Helloworld::initOnce();
parent::__construct($data);
}
/**
* Generated from protobuf field <code>string name = 1;</code>
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Generated from protobuf field <code>string name = 1;</code>
* @param string $var
* @return $this
*/
public function setName($var)
{
GPBUtil::checkString($var, True);
$this->name = $var;
return $this;
}
}

@ -2,8 +2,8 @@
"name": "grpc/grpc-demo",
"description": "gRPC example for PHP",
"require": {
"grpc/grpc": "^v1.3.0",
"google/protobuf": "^v3.3.0"
"grpc/grpc": "^v1.30.0",
"google/protobuf": "^v3.12.2"
},
"autoload": {
"psr-4": {

@ -1,8 +1,8 @@
{
"name": "grpc-php/echo-example",
"require": {
"grpc/grpc": "^v1.22.0",
"google/protobuf": "^3.7.0"
"grpc/grpc": "^v1.30.0",
"google/protobuf": "^3.12.2"
},
"autoload": {
"psr-4": {

@ -0,0 +1,47 @@
<?php
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require dirname(__FILE__) . '/../../src/php/lib/Grpc/MethodDescriptor.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/Status.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerCallReader.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerCallWriter.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerContext.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/RpcServer.php';
require dirname(__FILE__) . '/vendor/autoload.php';
require dirname(__FILE__) . '/route_guide/RouteGuideService.php';
class Greeter extends \Helloworld\GreeterStub
{
public function SayHello(
\Helloworld\HelloRequest $request,
\Grpc\ServerContext $serverContext
): ?\Helloworld\HelloReply {
$name = $request->getName();
$response = new \Helloworld\HelloReply();
$response->setMessage("Hello " . $name);
return $response;
}
}
$server = new \Grpc\RpcServer();
$server->addHttp2Port('0.0.0.0:50051');
$server->handle(new RouteGuideService(null));
$server->handle(new Greeter());
$server->run();

@ -13,4 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
protoc --proto_path=../protos --php_out=. --grpc_out=. --plugin=protoc-gen-grpc=../../bins/opt/grpc_php_plugin ../protos/helloworld.proto
set -e
cd $(dirname $0)/../..
# protoc and grpc_*_plugin binaries can be obtained by running
# $ bazel build @com_google_protobuf//:protoc //src/compiler:all
PROTOC=bazel-bin/external/com_google_protobuf/protoc
PLUGIN=protoc-gen-grpc=bazel-bin/src/compiler/grpc_php_plugin
$PROTOC --proto_path=examples/protos \
--php_out=examples/php \
--grpc_out=generate_server:examples/php \
--plugin=$PLUGIN examples/protos/helloworld.proto

@ -0,0 +1,44 @@
<?php
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require dirname(__FILE__) . '/../../src/php/lib/Grpc/MethodDescriptor.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/Status.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerCallReader.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerCallWriter.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/ServerContext.php';
require dirname(__FILE__) . '/../../src/php/lib/Grpc/RpcServer.php';
require dirname(__FILE__) . '/vendor/autoload.php';
class Greeter extends Helloworld\GreeterStub
{
public function SayHello(
\Helloworld\HelloRequest $request,
\Grpc\ServerContext $serverContext
): ?\Helloworld\HelloReply {
$name = $request->getName();
$response = new \Helloworld\HelloReply();
$response->setMessage("Hello " . $name);
return $response;
}
}
$server = new \Grpc\RpcServer();
$server->addHttp2Port('0.0.0.0:50051');
$server->handle(new Greeter());
$server->run();

@ -0,0 +1,182 @@
<?php
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
class RouteGuideService extends \Routeguide\RouteGuideStub
{
public function __construct($dbFilePath)
{
$dbFilePath = $dbFilePath ?? dirname(__FILE__) . '/route_guide_db.json';
$dbData = file_get_contents($dbFilePath);
if (!$dbData) {
throw new InvalidArgumentException(
"Error reading route db file: " . $dbFilePath
);
}
$featureList = json_decode($dbData);
if (!$featureList) {
throw new InvalidArgumentException(
"Error decoding route db file: " . $dbFilePath
);
}
foreach ($featureList as $feature) {
array_push($this->featureList, new Routeguide\Feature([
'name' => $feature->name,
'location' => new Routeguide\Point([
'latitude' => $feature->location->latitude,
'longitude' => $feature->location->longitude,
]),
]));
}
}
private function findFeature(\Routeguide\Point $point)
{
foreach ($this->featureList as $feature) {
$location = $feature->getLocation();
if (
$location->getLatitude() === $point->getLatitude()
&& $location->getLongitude() === $point->getLongitude()
) {
return $feature;
}
}
return null;
}
// The formula is based on http://mathforum.org/library/drmath/view/51879.html
private function calculateDistance(
\Routeguide\Point $start,
\Routeguide\Point $end
) {
$toRadians = function (float $num) {
return $num * 3.1415926 / 180;
};
$coordFactor = 10000000.0;
$R = 6371000; // metres
$lat_1 = $start->getLatitude() / $coordFactor;
$lat_2 = $end->getLatitude() / $coordFactor;
$lon_1 = $start->getLongitude() / $coordFactor;
$lon_2 = $end->getLongitude() / $coordFactor;
$lat_rad_1 = $toRadians($lat_1);
$lat_rad_2 = $toRadians($lat_2);
$delta_lat_rad = $toRadians($lat_2 - $lat_1);
$delta_lon_rad = $toRadians($lon_2 - $lon_1);
$a = pow(sin($delta_lat_rad / 2), 2) +
cos($lat_rad_1) * cos($lat_rad_2) * pow(sin($delta_lon_rad / 2), 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
return $R * $c;
}
public function GetFeature(
\Routeguide\Point $request,
\Grpc\ServerContext $serverContext
): ?\Routeguide\Feature {
$feature = $this->findFeature($request);
$notFoundFeature = new Routeguide\Feature([
'name' => '',
'location' => $request,
]);
return $feature ?? $notFoundFeature;
}
public function ListFeatures(
\Routeguide\Rectangle $request,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $serverContext
): void {
$lo = $request->getLo();
$hi = $request->getHi();
$left = min($lo->getLongitude(), $hi->getLongitude());
$right = max($lo->getLongitude(), $hi->getLongitude());
$top = max($lo->getLatitude(), $hi->getLatitude());
$bottom = min($lo->getLatitude(), $hi->getLatitude());
foreach ($this->featureList as $feature) {
$longitude = $feature->getLocation()->getLongitude();
$latitude = $feature->getLocation()->getLatitude();
if (
$longitude >= $left && $longitude <= $right
&& $latitude >= $bottom && $latitude <= $top
) {
$writer->write($feature);
}
}
$writer->finish();
}
public function RecordRoute(
\Grpc\ServerCallReader $reader,
\Grpc\ServerContext $serverContext
): ?\Routeguide\RouteSummary {
$point_count = 0;
$feature_count = 0;
$distance = 0;
$previous = null;
$start_time = time();
while ($point = $reader->read()) {
$point_count++;
$feature = $this->findFeature($point);
if ($feature) {
$feature_count++;
if ($previous) {
$distance += $this->calculateDistance($previous, $point);
}
$previous = $point;
}
}
$summary = new \Routeguide\RouteSummary();
$summary->setPointCount($point_count);
$summary->setFeatureCount($feature_count);
$summary->setDistance($distance);
$summary->setElapsedTime(time() - $start_time);
return $summary;
}
public function RouteChat(
\Grpc\ServerCallReader $reader,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $serverContext
): void {
while ($note = $reader->read()) {
foreach ($this->received_notes as $n) {
if (
$n->getLocation()->getLatitude() ===
$note->getLocation()->getLatitude()
&& $n->getLocation()->getLongitude() ===
$note->getLocation()->getLongitude()
) {
$writer->write($n);
}
}
array_push($this->received_notes, $note);
}
$writer->finish();
}
private $received_notes = [];
private $featureList = [];
}

@ -0,0 +1,112 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* A feature names something at a given point.
* If a feature could not be named, the name is empty.
*
* Generated from protobuf message <code>routeguide.Feature</code>
*/
class Feature extends \Google\Protobuf\Internal\Message
{
/**
* The name of the feature.
*
* Generated from protobuf field <code>string name = 1;</code>
*/
protected $name = '';
/**
* The point where the feature is detected.
*
* Generated from protobuf field <code>.routeguide.Point location = 2;</code>
*/
protected $location = null;
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type string $name
* The name of the feature.
* @type \Routeguide\Point $location
* The point where the feature is detected.
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\RouteGuide::initOnce();
parent::__construct($data);
}
/**
* The name of the feature.
*
* Generated from protobuf field <code>string name = 1;</code>
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* The name of the feature.
*
* Generated from protobuf field <code>string name = 1;</code>
* @param string $var
* @return $this
*/
public function setName($var)
{
GPBUtil::checkString($var, True);
$this->name = $var;
return $this;
}
/**
* The point where the feature is detected.
*
* Generated from protobuf field <code>.routeguide.Point location = 2;</code>
* @return \Routeguide\Point|null
*/
public function getLocation()
{
return isset($this->location) ? $this->location : null;
}
public function hasLocation()
{
return isset($this->location);
}
public function clearLocation()
{
unset($this->location);
}
/**
* The point where the feature is detected.
*
* Generated from protobuf field <code>.routeguide.Point location = 2;</code>
* @param \Routeguide\Point $var
* @return $this
*/
public function setLocation($var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->location = $var;
return $this;
}
}

@ -0,0 +1,90 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* Points are represented as latitude-longitude pairs in the E7 representation
* (degrees multiplied by 10**7 and rounded to the nearest integer).
* Latitudes should be in the range +/- 90 degrees and longitude should be in
* the range +/- 180 degrees (inclusive).
*
* Generated from protobuf message <code>routeguide.Point</code>
*/
class Point extends \Google\Protobuf\Internal\Message
{
/**
* Generated from protobuf field <code>int32 latitude = 1;</code>
*/
protected $latitude = 0;
/**
* Generated from protobuf field <code>int32 longitude = 2;</code>
*/
protected $longitude = 0;
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type int $latitude
* @type int $longitude
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\RouteGuide::initOnce();
parent::__construct($data);
}
/**
* Generated from protobuf field <code>int32 latitude = 1;</code>
* @return int
*/
public function getLatitude()
{
return $this->latitude;
}
/**
* Generated from protobuf field <code>int32 latitude = 1;</code>
* @param int $var
* @return $this
*/
public function setLatitude($var)
{
GPBUtil::checkInt32($var);
$this->latitude = $var;
return $this;
}
/**
* Generated from protobuf field <code>int32 longitude = 2;</code>
* @return int
*/
public function getLongitude()
{
return $this->longitude;
}
/**
* Generated from protobuf field <code>int32 longitude = 2;</code>
* @param int $var
* @return $this
*/
public function setLongitude($var)
{
GPBUtil::checkInt32($var);
$this->longitude = $var;
return $this;
}
}

@ -0,0 +1,122 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* A latitude-longitude rectangle, represented as two diagonally opposite
* points "lo" and "hi".
*
* Generated from protobuf message <code>routeguide.Rectangle</code>
*/
class Rectangle extends \Google\Protobuf\Internal\Message
{
/**
* One corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point lo = 1;</code>
*/
protected $lo = null;
/**
* The other corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point hi = 2;</code>
*/
protected $hi = null;
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type \Routeguide\Point $lo
* One corner of the rectangle.
* @type \Routeguide\Point $hi
* The other corner of the rectangle.
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\RouteGuide::initOnce();
parent::__construct($data);
}
/**
* One corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point lo = 1;</code>
* @return \Routeguide\Point|null
*/
public function getLo()
{
return isset($this->lo) ? $this->lo : null;
}
public function hasLo()
{
return isset($this->lo);
}
public function clearLo()
{
unset($this->lo);
}
/**
* One corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point lo = 1;</code>
* @param \Routeguide\Point $var
* @return $this
*/
public function setLo($var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->lo = $var;
return $this;
}
/**
* The other corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point hi = 2;</code>
* @return \Routeguide\Point|null
*/
public function getHi()
{
return isset($this->hi) ? $this->hi : null;
}
public function hasHi()
{
return isset($this->hi);
}
public function clearHi()
{
unset($this->hi);
}
/**
* The other corner of the rectangle.
*
* Generated from protobuf field <code>.routeguide.Point hi = 2;</code>
* @param \Routeguide\Point $var
* @return $this
*/
public function setHi($var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->hi = $var;
return $this;
}
}

@ -0,0 +1,105 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace Routeguide;
/**
* Interface exported by the server.
*/
class RouteGuideClient 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);
}
/**
* A simple RPC.
*
* Obtains the feature at a given position.
*
* A feature with an empty name is returned if there's no feature at the given
* position.
* @param \Routeguide\Point $argument input argument
* @param array $metadata metadata
* @param array $options call options
* @return \Grpc\UnaryCall
*/
public function GetFeature(\Routeguide\Point $argument,
$metadata = [], $options = []) {
return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature',
$argument,
['\Routeguide\Feature', 'decode'],
$metadata, $options);
}
/**
* A server-to-client streaming RPC.
*
* Obtains the Features available within the given Rectangle. Results are
* streamed rather than returned at once (e.g. in a response message with a
* repeated field), as the rectangle may cover a large area and contain a
* huge number of features.
* @param \Routeguide\Rectangle $argument input argument
* @param array $metadata metadata
* @param array $options call options
* @return \Grpc\ServerStreamingCall
*/
public function ListFeatures(\Routeguide\Rectangle $argument,
$metadata = [], $options = []) {
return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures',
$argument,
['\Routeguide\Feature', 'decode'],
$metadata, $options);
}
/**
* A client-to-server streaming RPC.
*
* Accepts a stream of Points on a route being traversed, returning a
* RouteSummary when traversal is completed.
* @param array $metadata metadata
* @param array $options call options
* @return \Grpc\ClientStreamingCall
*/
public function RecordRoute($metadata = [], $options = []) {
return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute',
['\Routeguide\RouteSummary','decode'],
$metadata, $options);
}
/**
* A Bidirectional streaming RPC.
*
* Accepts a stream of RouteNotes sent while a route is being traversed,
* while receiving other RouteNotes (e.g. from other users).
* @param array $metadata metadata
* @param array $options call options
* @return \Grpc\BidiStreamingCall
*/
public function RouteChat($metadata = [], $options = []) {
return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat',
['\Routeguide\RouteNote','decode'],
$metadata, $options);
}
}

@ -0,0 +1,139 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
namespace Routeguide;
/**
* Interface exported by the server.
*/
class RouteGuideStub {
/**
* A simple RPC.
*
* Obtains the feature at a given position.
*
* A feature with an empty name is returned if there's no feature at the given
* position.
* @param \Routeguide\Point $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Routeguide\Feature for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function GetFeature(
\Routeguide\Point $request,
\Grpc\ServerContext $context
): ?\Routeguide\Feature {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* A server-to-client streaming RPC.
*
* Obtains the Features available within the given Rectangle. Results are
* streamed rather than returned at once (e.g. in a response message with a
* repeated field), as the rectangle may cover a large area and contain a
* huge number of features.
* @param \Routeguide\Rectangle $request client request
* @param \Grpc\ServerCallWriter $writer write response data of \Routeguide\Feature
* @param \Grpc\ServerContext $context server request context
* @return void
*/
public function ListFeatures(
\Routeguide\Rectangle $request,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
$writer->finish();
}
/**
* A client-to-server streaming RPC.
*
* Accepts a stream of Points on a route being traversed, returning a
* RouteSummary when traversal is completed.
* @param \Grpc\ServerCallReader $reader read client request data of \Routeguide\Point
* @param \Grpc\ServerContext $context server request context
* @return \Routeguide\RouteSummary for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function RecordRoute(
\Grpc\ServerCallReader $reader,
\Grpc\ServerContext $context
): ?\Routeguide\RouteSummary {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* A Bidirectional streaming RPC.
*
* Accepts a stream of RouteNotes sent while a route is being traversed,
* while receiving other RouteNotes (e.g. from other users).
* @param \Grpc\ServerCallReader $reader read client request data of \Routeguide\RouteNote
* @param \Grpc\ServerCallWriter $writer write response data of \Routeguide\RouteNote
* @param \Grpc\ServerContext $context server request context
* @return void
*/
public function RouteChat(
\Grpc\ServerCallReader $reader,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
$writer->finish();
}
/**
* 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 [
'/routeguide.RouteGuide/GetFeature' => new \Grpc\MethodDescriptor(
$this,
'GetFeature',
'\Routeguide\Point',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/routeguide.RouteGuide/ListFeatures' => new \Grpc\MethodDescriptor(
$this,
'ListFeatures',
'\Routeguide\Rectangle',
\Grpc\MethodDescriptor::SERVER_STREAMING_CALL
),
'/routeguide.RouteGuide/RecordRoute' => new \Grpc\MethodDescriptor(
$this,
'RecordRoute',
'\Routeguide\Point',
\Grpc\MethodDescriptor::CLIENT_STREAMING_CALL
),
'/routeguide.RouteGuide/RouteChat' => new \Grpc\MethodDescriptor(
$this,
'RouteChat',
'\Routeguide\RouteNote',
\Grpc\MethodDescriptor::BIDI_STREAMING_CALL
),
];
}
}

@ -0,0 +1,111 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* A RouteNote is a message sent while at a given point.
*
* Generated from protobuf message <code>routeguide.RouteNote</code>
*/
class RouteNote extends \Google\Protobuf\Internal\Message
{
/**
* The location from which the message is sent.
*
* Generated from protobuf field <code>.routeguide.Point location = 1;</code>
*/
protected $location = null;
/**
* The message to be sent.
*
* Generated from protobuf field <code>string message = 2;</code>
*/
protected $message = '';
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type \Routeguide\Point $location
* The location from which the message is sent.
* @type string $message
* The message to be sent.
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\RouteGuide::initOnce();
parent::__construct($data);
}
/**
* The location from which the message is sent.
*
* Generated from protobuf field <code>.routeguide.Point location = 1;</code>
* @return \Routeguide\Point|null
*/
public function getLocation()
{
return isset($this->location) ? $this->location : null;
}
public function hasLocation()
{
return isset($this->location);
}
public function clearLocation()
{
unset($this->location);
}
/**
* The location from which the message is sent.
*
* Generated from protobuf field <code>.routeguide.Point location = 1;</code>
* @param \Routeguide\Point $var
* @return $this
*/
public function setLocation($var)
{
GPBUtil::checkMessage($var, \Routeguide\Point::class);
$this->location = $var;
return $this;
}
/**
* The message to be sent.
*
* Generated from protobuf field <code>string message = 2;</code>
* @return string
*/
public function getMessage()
{
return $this->message;
}
/**
* The message to be sent.
*
* Generated from protobuf field <code>string message = 2;</code>
* @param string $var
* @return $this
*/
public function setMessage($var)
{
GPBUtil::checkString($var, True);
$this->message = $var;
return $this;
}
}

@ -0,0 +1,172 @@
<?php
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: route_guide.proto
namespace Routeguide;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\Internal\GPBUtil;
/**
* A RouteSummary is received in response to a RecordRoute rpc.
* It contains the number of individual points received, the number of
* detected features, and the total distance covered as the cumulative sum of
* the distance between each point.
*
* Generated from protobuf message <code>routeguide.RouteSummary</code>
*/
class RouteSummary extends \Google\Protobuf\Internal\Message
{
/**
* The number of points received.
*
* Generated from protobuf field <code>int32 point_count = 1;</code>
*/
protected $point_count = 0;
/**
* The number of known features passed while traversing the route.
*
* Generated from protobuf field <code>int32 feature_count = 2;</code>
*/
protected $feature_count = 0;
/**
* The distance covered in metres.
*
* Generated from protobuf field <code>int32 distance = 3;</code>
*/
protected $distance = 0;
/**
* The duration of the traversal in seconds.
*
* Generated from protobuf field <code>int32 elapsed_time = 4;</code>
*/
protected $elapsed_time = 0;
/**
* Constructor.
*
* @param array $data {
* Optional. Data for populating the Message object.
*
* @type int $point_count
* The number of points received.
* @type int $feature_count
* The number of known features passed while traversing the route.
* @type int $distance
* The distance covered in metres.
* @type int $elapsed_time
* The duration of the traversal in seconds.
* }
*/
public function __construct($data = NULL) {
\GPBMetadata\RouteGuide::initOnce();
parent::__construct($data);
}
/**
* The number of points received.
*
* Generated from protobuf field <code>int32 point_count = 1;</code>
* @return int
*/
public function getPointCount()
{
return $this->point_count;
}
/**
* The number of points received.
*
* Generated from protobuf field <code>int32 point_count = 1;</code>
* @param int $var
* @return $this
*/
public function setPointCount($var)
{
GPBUtil::checkInt32($var);
$this->point_count = $var;
return $this;
}
/**
* The number of known features passed while traversing the route.
*
* Generated from protobuf field <code>int32 feature_count = 2;</code>
* @return int
*/
public function getFeatureCount()
{
return $this->feature_count;
}
/**
* The number of known features passed while traversing the route.
*
* Generated from protobuf field <code>int32 feature_count = 2;</code>
* @param int $var
* @return $this
*/
public function setFeatureCount($var)
{
GPBUtil::checkInt32($var);
$this->feature_count = $var;
return $this;
}
/**
* The distance covered in metres.
*
* Generated from protobuf field <code>int32 distance = 3;</code>
* @return int
*/
public function getDistance()
{
return $this->distance;
}
/**
* The distance covered in metres.
*
* Generated from protobuf field <code>int32 distance = 3;</code>
* @param int $var
* @return $this
*/
public function setDistance($var)
{
GPBUtil::checkInt32($var);
$this->distance = $var;
return $this;
}
/**
* The duration of the traversal in seconds.
*
* Generated from protobuf field <code>int32 elapsed_time = 4;</code>
* @return int
*/
public function getElapsedTime()
{
return $this->elapsed_time;
}
/**
* The duration of the traversal in seconds.
*
* Generated from protobuf field <code>int32 elapsed_time = 4;</code>
* @param int $var
* @return $this
*/
public function setElapsedTime($var)
{
GPBUtil::checkInt32($var);
$this->elapsed_time = $var;
return $this;
}
}

@ -0,0 +1,601 @@
[{
"location": {
"latitude": 407838351,
"longitude": -746143763
},
"name": "Patriots Path, Mendham, NJ 07945, USA"
}, {
"location": {
"latitude": 408122808,
"longitude": -743999179
},
"name": "101 New Jersey 10, Whippany, NJ 07981, USA"
}, {
"location": {
"latitude": 413628156,
"longitude": -749015468
},
"name": "U.S. 6, Shohola, PA 18458, USA"
}, {
"location": {
"latitude": 419999544,
"longitude": -740371136
},
"name": "5 Conners Road, Kingston, NY 12401, USA"
}, {
"location": {
"latitude": 414008389,
"longitude": -743951297
},
"name": "Mid Hudson Psychiatric Center, New Hampton, NY 10958, USA"
}, {
"location": {
"latitude": 419611318,
"longitude": -746524769
},
"name": "287 Flugertown Road, Livingston Manor, NY 12758, USA"
}, {
"location": {
"latitude": 406109563,
"longitude": -742186778
},
"name": "4001 Tremley Point Road, Linden, NJ 07036, USA"
}, {
"location": {
"latitude": 416802456,
"longitude": -742370183
},
"name": "352 South Mountain Road, Wallkill, NY 12589, USA"
}, {
"location": {
"latitude": 412950425,
"longitude": -741077389
},
"name": "Bailey Turn Road, Harriman, NY 10926, USA"
}, {
"location": {
"latitude": 412144655,
"longitude": -743949739
},
"name": "193-199 Wawayanda Road, Hewitt, NJ 07421, USA"
}, {
"location": {
"latitude": 415736605,
"longitude": -742847522
},
"name": "406-496 Ward Avenue, Pine Bush, NY 12566, USA"
}, {
"location": {
"latitude": 413843930,
"longitude": -740501726
},
"name": "162 Merrill Road, Highland Mills, NY 10930, USA"
}, {
"location": {
"latitude": 410873075,
"longitude": -744459023
},
"name": "Clinton Road, West Milford, NJ 07480, USA"
}, {
"location": {
"latitude": 412346009,
"longitude": -744026814
},
"name": "16 Old Brook Lane, Warwick, NY 10990, USA"
}, {
"location": {
"latitude": 402948455,
"longitude": -747903913
},
"name": "3 Drake Lane, Pennington, NJ 08534, USA"
}, {
"location": {
"latitude": 406337092,
"longitude": -740122226
},
"name": "6324 8th Avenue, Brooklyn, NY 11220, USA"
}, {
"location": {
"latitude": 406421967,
"longitude": -747727624
},
"name": "1 Merck Access Road, Whitehouse Station, NJ 08889, USA"
}, {
"location": {
"latitude": 416318082,
"longitude": -749677716
},
"name": "78-98 Schalck Road, Narrowsburg, NY 12764, USA"
}, {
"location": {
"latitude": 415301720,
"longitude": -748416257
},
"name": "282 Lakeview Drive Road, Highland Lake, NY 12743, USA"
}, {
"location": {
"latitude": 402647019,
"longitude": -747071791
},
"name": "330 Evelyn Avenue, Hamilton Township, NJ 08619, USA"
}, {
"location": {
"latitude": 412567807,
"longitude": -741058078
},
"name": "New York State Reference Route 987E, Southfields, NY 10975, USA"
}, {
"location": {
"latitude": 416855156,
"longitude": -744420597
},
"name": "103-271 Tempaloni Road, Ellenville, NY 12428, USA"
}, {
"location": {
"latitude": 404663628,
"longitude": -744820157
},
"name": "1300 Airport Road, North Brunswick Township, NJ 08902, USA"
}, {
"location": {
"latitude": 407113723,
"longitude": -749746483
},
"name": ""
}, {
"location": {
"latitude": 402133926,
"longitude": -743613249
},
"name": ""
}, {
"location": {
"latitude": 400273442,
"longitude": -741220915
},
"name": ""
}, {
"location": {
"latitude": 411236786,
"longitude": -744070769
},
"name": ""
}, {
"location": {
"latitude": 411633782,
"longitude": -746784970
},
"name": "211-225 Plains Road, Augusta, NJ 07822, USA"
}, {
"location": {
"latitude": 415830701,
"longitude": -742952812
},
"name": ""
}, {
"location": {
"latitude": 413447164,
"longitude": -748712898
},
"name": "165 Pedersen Ridge Road, Milford, PA 18337, USA"
}, {
"location": {
"latitude": 405047245,
"longitude": -749800722
},
"name": "100-122 Locktown Road, Frenchtown, NJ 08825, USA"
}, {
"location": {
"latitude": 418858923,
"longitude": -746156790
},
"name": ""
}, {
"location": {
"latitude": 417951888,
"longitude": -748484944
},
"name": "650-652 Willi Hill Road, Swan Lake, NY 12783, USA"
}, {
"location": {
"latitude": 407033786,
"longitude": -743977337
},
"name": "26 East 3rd Street, New Providence, NJ 07974, USA"
}, {
"location": {
"latitude": 417548014,
"longitude": -740075041
},
"name": ""
}, {
"location": {
"latitude": 410395868,
"longitude": -744972325
},
"name": ""
}, {
"location": {
"latitude": 404615353,
"longitude": -745129803
},
"name": ""
}, {
"location": {
"latitude": 406589790,
"longitude": -743560121
},
"name": "611 Lawrence Avenue, Westfield, NJ 07090, USA"
}, {
"location": {
"latitude": 414653148,
"longitude": -740477477
},
"name": "18 Lannis Avenue, New Windsor, NY 12553, USA"
}, {
"location": {
"latitude": 405957808,
"longitude": -743255336
},
"name": "82-104 Amherst Avenue, Colonia, NJ 07067, USA"
}, {
"location": {
"latitude": 411733589,
"longitude": -741648093
},
"name": "170 Seven Lakes Drive, Sloatsburg, NY 10974, USA"
}, {
"location": {
"latitude": 412676291,
"longitude": -742606606
},
"name": "1270 Lakes Road, Monroe, NY 10950, USA"
}, {
"location": {
"latitude": 409224445,
"longitude": -748286738
},
"name": "509-535 Alphano Road, Great Meadows, NJ 07838, USA"
}, {
"location": {
"latitude": 406523420,
"longitude": -742135517
},
"name": "652 Garden Street, Elizabeth, NJ 07202, USA"
}, {
"location": {
"latitude": 401827388,
"longitude": -740294537
},
"name": "349 Sea Spray Court, Neptune City, NJ 07753, USA"
}, {
"location": {
"latitude": 410564152,
"longitude": -743685054
},
"name": "13-17 Stanley Street, West Milford, NJ 07480, USA"
}, {
"location": {
"latitude": 408472324,
"longitude": -740726046
},
"name": "47 Industrial Avenue, Teterboro, NJ 07608, USA"
}, {
"location": {
"latitude": 412452168,
"longitude": -740214052
},
"name": "5 White Oak Lane, Stony Point, NY 10980, USA"
}, {
"location": {
"latitude": 409146138,
"longitude": -746188906
},
"name": "Berkshire Valley Management Area Trail, Jefferson, NJ, USA"
}, {
"location": {
"latitude": 404701380,
"longitude": -744781745
},
"name": "1007 Jersey Avenue, New Brunswick, NJ 08901, USA"
}, {
"location": {
"latitude": 409642566,
"longitude": -746017679
},
"name": "6 East Emerald Isle Drive, Lake Hopatcong, NJ 07849, USA"
}, {
"location": {
"latitude": 408031728,
"longitude": -748645385
},
"name": "1358-1474 New Jersey 57, Port Murray, NJ 07865, USA"
}, {
"location": {
"latitude": 413700272,
"longitude": -742135189
},
"name": "367 Prospect Road, Chester, NY 10918, USA"
}, {
"location": {
"latitude": 404310607,
"longitude": -740282632
},
"name": "10 Simon Lake Drive, Atlantic Highlands, NJ 07716, USA"
}, {
"location": {
"latitude": 409319800,
"longitude": -746201391
},
"name": "11 Ward Street, Mount Arlington, NJ 07856, USA"
}, {
"location": {
"latitude": 406685311,
"longitude": -742108603
},
"name": "300-398 Jefferson Avenue, Elizabeth, NJ 07201, USA"
}, {
"location": {
"latitude": 419018117,
"longitude": -749142781
},
"name": "43 Dreher Road, Roscoe, NY 12776, USA"
}, {
"location": {
"latitude": 412856162,
"longitude": -745148837
},
"name": "Swan Street, Pine Island, NY 10969, USA"
}, {
"location": {
"latitude": 416560744,
"longitude": -746721964
},
"name": "66 Pleasantview Avenue, Monticello, NY 12701, USA"
}, {
"location": {
"latitude": 405314270,
"longitude": -749836354
},
"name": ""
}, {
"location": {
"latitude": 414219548,
"longitude": -743327440
},
"name": ""
}, {
"location": {
"latitude": 415534177,
"longitude": -742900616
},
"name": "565 Winding Hills Road, Montgomery, NY 12549, USA"
}, {
"location": {
"latitude": 406898530,
"longitude": -749127080
},
"name": "231 Rocky Run Road, Glen Gardner, NJ 08826, USA"
}, {
"location": {
"latitude": 407586880,
"longitude": -741670168
},
"name": "100 Mount Pleasant Avenue, Newark, NJ 07104, USA"
}, {
"location": {
"latitude": 400106455,
"longitude": -742870190
},
"name": "517-521 Huntington Drive, Manchester Township, NJ 08759, USA"
}, {
"location": {
"latitude": 400066188,
"longitude": -746793294
},
"name": ""
}, {
"location": {
"latitude": 418803880,
"longitude": -744102673
},
"name": "40 Mountain Road, Napanoch, NY 12458, USA"
}, {
"location": {
"latitude": 414204288,
"longitude": -747895140
},
"name": ""
}, {
"location": {
"latitude": 414777405,
"longitude": -740615601
},
"name": ""
}, {
"location": {
"latitude": 415464475,
"longitude": -747175374
},
"name": "48 North Road, Forestburgh, NY 12777, USA"
}, {
"location": {
"latitude": 404062378,
"longitude": -746376177
},
"name": ""
}, {
"location": {
"latitude": 405688272,
"longitude": -749285130
},
"name": ""
}, {
"location": {
"latitude": 400342070,
"longitude": -748788996
},
"name": ""
}, {
"location": {
"latitude": 401809022,
"longitude": -744157964
},
"name": ""
}, {
"location": {
"latitude": 404226644,
"longitude": -740517141
},
"name": "9 Thompson Avenue, Leonardo, NJ 07737, USA"
}, {
"location": {
"latitude": 410322033,
"longitude": -747871659
},
"name": ""
}, {
"location": {
"latitude": 407100674,
"longitude": -747742727
},
"name": ""
}, {
"location": {
"latitude": 418811433,
"longitude": -741718005
},
"name": "213 Bush Road, Stone Ridge, NY 12484, USA"
}, {
"location": {
"latitude": 415034302,
"longitude": -743850945
},
"name": ""
}, {
"location": {
"latitude": 411349992,
"longitude": -743694161
},
"name": ""
}, {
"location": {
"latitude": 404839914,
"longitude": -744759616
},
"name": "1-17 Bergen Court, New Brunswick, NJ 08901, USA"
}, {
"location": {
"latitude": 414638017,
"longitude": -745957854
},
"name": "35 Oakland Valley Road, Cuddebackville, NY 12729, USA"
}, {
"location": {
"latitude": 412127800,
"longitude": -740173578
},
"name": ""
}, {
"location": {
"latitude": 401263460,
"longitude": -747964303
},
"name": ""
}, {
"location": {
"latitude": 412843391,
"longitude": -749086026
},
"name": ""
}, {
"location": {
"latitude": 418512773,
"longitude": -743067823
},
"name": ""
}, {
"location": {
"latitude": 404318328,
"longitude": -740835638
},
"name": "42-102 Main Street, Belford, NJ 07718, USA"
}, {
"location": {
"latitude": 419020746,
"longitude": -741172328
},
"name": ""
}, {
"location": {
"latitude": 404080723,
"longitude": -746119569
},
"name": ""
}, {
"location": {
"latitude": 401012643,
"longitude": -744035134
},
"name": ""
}, {
"location": {
"latitude": 404306372,
"longitude": -741079661
},
"name": ""
}, {
"location": {
"latitude": 403966326,
"longitude": -748519297
},
"name": ""
}, {
"location": {
"latitude": 405002031,
"longitude": -748407866
},
"name": ""
}, {
"location": {
"latitude": 409532885,
"longitude": -742200683
},
"name": ""
}, {
"location": {
"latitude": 416851321,
"longitude": -742674555
},
"name": ""
}, {
"location": {
"latitude": 406411633,
"longitude": -741722051
},
"name": "3387 Richmond Terrace, Staten Island, NY 10303, USA"
}, {
"location": {
"latitude": 413069058,
"longitude": -744597778
},
"name": "261 Van Sickle Road, Goshen, NY 10924, USA"
}, {
"location": {
"latitude": 418465462,
"longitude": -746859398
},
"name": ""
}, {
"location": {
"latitude": 411733222,
"longitude": -744228360
},
"name": ""
}, {
"location": {
"latitude": 410248224,
"longitude": -747127767
},
"name": "3 Hasta Way, Newton, NJ 07860, USA"
}]

@ -13,4 +13,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
protoc --proto_path=./../../protos --php_out=./ --grpc_out=./ --plugin=protoc-gen-grpc=./../../../bins/opt/grpc_php_plugin ./../../protos/route_guide.proto
set -e
cd $(dirname $0)/../../..
# protoc and grpc_*_plugin binaries can be obtained by running
# $ bazel build @com_google_protobuf//:protoc //src/compiler:all
PROTOC=bazel-bin/external/com_google_protobuf/protoc
PLUGIN=protoc-gen-grpc=bazel-bin/src/compiler/grpc_php_plugin
$PROTOC --proto_path=examples/protos \
--php_out=examples/php/route_guide \
--grpc_out=generate_server:examples/php/route_guide \
--plugin=$PLUGIN examples/protos/route_guide.proto

@ -0,0 +1,34 @@
<?php
/*
*
* Copyright 2020 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/MethodDescriptor.php';
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/Status.php';
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/ServerCallReader.php';
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/ServerCallWriter.php';
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/ServerContext.php';
require dirname(__FILE__) . '/../../../src/php/lib/Grpc/RpcServer.php';
require dirname(__FILE__) . '/../vendor/autoload.php';
require dirname(__FILE__) . '/RouteGuideService.php';
$routeDbFile = $argv[1];
$server = new \Grpc\RpcServer();
$server->addHttp2Port('0.0.0.0:50051');
$server->handle(new RouteGuideService($routeDbFile));
$server->run();

@ -131,34 +131,177 @@ void PrintMethod(const MethodDescriptor* method, Printer* out) {
out->Print("}\n\n");
}
// Prints out the service descriptor object
void PrintService(const ServiceDescriptor* service,
const std::string& class_suffix, Printer* out) {
void PrintServerMethod(const MethodDescriptor* method, Printer* out) {
map<std::string, std::string> vars;
const Descriptor* input_type = method->input_type();
const Descriptor* output_type = method->output_type();
vars["service_name"] = method->service()->full_name();
vars["method_name"] = method->name();
vars["input_type_id"] =
MessageIdentifierName(GeneratedClassName(input_type), input_type->file());
vars["output_type_id"] = MessageIdentifierName(
GeneratedClassName(output_type), output_type->file());
out->Print("/**\n");
out->Print(GetPHPComments(service, " *").c_str());
out->Print(" */\n");
vars["name"] = GetPHPServiceClassname(service, class_suffix);
out->Print(vars, "class $name$ extends \\Grpc\\BaseStub {\n\n");
out->Print(GetPHPComments(method, " *").c_str());
const char* method_template;
if (method->client_streaming() && method->server_streaming()) {
method_template =
" * @param \\Grpc\\ServerCallReader $$reader read client request data "
"of \\$input_type_id$\n"
" * @param \\Grpc\\ServerCallWriter $$writer write response data of "
"\\$output_type_id$\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return void\n"
" */\n"
"public function $method_name$(\n"
" \\Grpc\\ServerCallReader $$reader,\n"
" \\Grpc\\ServerCallWriter $$writer,\n"
" \\Grpc\\ServerContext $$context\n"
"): void {\n"
" $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
" $$writer->finish();\n"
"}\n\n";
} else if (method->client_streaming()) {
method_template =
" * @param \\Grpc\\ServerCallReader $$reader read client request data "
"of \\$input_type_id$\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return \\$output_type_id$ for response data, null if if error "
"occured\n"
" * initial metadata (if any) and status (if not ok) should be set "
"to $$context\n"
" */\n"
"public function $method_name$(\n"
" \\Grpc\\ServerCallReader $$reader,\n"
" \\Grpc\\ServerContext $$context\n"
"): ?\\$output_type_id$ {\n"
" $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
" return null;\n"
"}\n\n";
} else if (method->server_streaming()) {
method_template =
" * @param \\$input_type_id$ $$request client request\n"
" * @param \\Grpc\\ServerCallWriter $$writer write response data of "
"\\$output_type_id$\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return void\n"
" */\n"
"public function $method_name$(\n"
" \\$input_type_id$ $$request,\n"
" \\Grpc\\ServerCallWriter $$writer,\n"
" \\Grpc\\ServerContext $$context\n"
"): void {\n"
" $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
" $$writer->finish();\n"
"}\n\n";
} else {
method_template =
" * @param \\$input_type_id$ $$request client request\n"
" * @param \\Grpc\\ServerContext $$context server request context\n"
" * @return \\$output_type_id$ for response data, null if if error "
"occured\n"
" * initial metadata (if any) and status (if not ok) should be set "
"to $$context\n"
" */\n"
"public function $method_name$(\n"
" \\$input_type_id$ $$request,\n"
" \\Grpc\\ServerContext $$context\n"
"): ?\\$output_type_id$ {\n"
" $$context->setStatus(\\Grpc\\Status::unimplemented());\n"
" return null;\n"
"}\n\n";
}
out->Print(vars, method_template);
}
void PrintServerMethodDescriptors(const ServiceDescriptor* service,
Printer* out) {
map<std::string, std::string> vars;
vars["service_name"] = service->full_name();
out->Print(
"/**\n"
" * Get the method descriptors of the service for server registration\n"
" *\n"
" * @return array of \\Grpc\\MethodDescriptor for the service methods\n"
" */\n"
"public final function getMethodDescriptors(): array\n{\n");
out->Indent();
out->Indent();
out->Print(
"/**\n * @param string $$hostname hostname\n"
" * @param array $$opts channel options\n"
" * @param \\Grpc\\Channel $$channel (optional) re-use channel "
"object\n */\n"
"public function __construct($$hostname, $$opts, "
"$$channel = null) {\n");
out->Print("return [\n");
out->Indent();
out->Indent();
out->Print("parent::__construct($$hostname, $$opts, $$channel);\n");
for (int i = 0; i < service->method_count(); i++) {
auto method = service->method(i);
auto input_type = method->input_type();
vars["method_name"] = method->name();
vars["input_type_id"] = MessageIdentifierName(
GeneratedClassName(input_type), input_type->file());
if (method->client_streaming() && method->server_streaming()) {
vars["call_type"] = "BIDI_STREAMING_CALL";
} else if (method->client_streaming()) {
vars["call_type"] = "CLIENT_STREAMING_CALL";
} else if (method->server_streaming()) {
vars["call_type"] = "SERVER_STREAMING_CALL";
} else {
vars["call_type"] = "UNARY_CALL";
}
out->Print(
vars,
"'/$service_name$/$method_name$' => new \\Grpc\\MethodDescriptor(\n"
" $$this,\n"
" '$method_name$',\n"
" '\\$input_type_id$',\n"
" \\Grpc\\MethodDescriptor::$call_type$\n"
"),\n");
}
out->Outdent();
out->Outdent();
out->Print("];\n");
out->Outdent();
out->Outdent();
out->Print("}\n\n");
}
// Prints out the service descriptor object
void PrintService(const ServiceDescriptor* service,
const std::string& class_suffix, bool is_server,
Printer* out) {
map<std::string, std::string> vars;
out->Print("/**\n");
out->Print(GetPHPComments(service, " *").c_str());
out->Print(" */\n");
vars["name"] = GetPHPServiceClassname(service, class_suffix, is_server);
vars["extends"] = is_server ? "" : "extends \\Grpc\\BaseStub ";
out->Print(vars, "class $name$ $extends${\n\n");
out->Indent();
out->Indent();
if (!is_server) {
out->Print(
"/**\n * @param string $$hostname hostname\n"
" * @param array $$opts channel options\n"
" * @param \\Grpc\\Channel $$channel (optional) re-use channel object\n"
" */\n"
"public function __construct($$hostname, $$opts, "
"$$channel = null) {\n");
out->Indent();
out->Indent();
out->Print("parent::__construct($$hostname, $$opts, $$channel);\n");
out->Outdent();
out->Outdent();
out->Print("}\n\n");
}
for (int i = 0; i < service->method_count(); i++) {
std::string method_name =
grpc_generator::LowercaseFirstLetter(service->method(i)->name());
PrintMethod(service->method(i), out);
if (is_server) {
PrintServerMethod(service->method(i), out);
} else {
PrintMethod(service->method(i), out);
}
}
if (is_server) {
PrintServerMethodDescriptors(service, out);
}
out->Outdent();
out->Outdent();
@ -168,7 +311,7 @@ void PrintService(const ServiceDescriptor* service,
std::string GenerateFile(const FileDescriptor* file,
const ServiceDescriptor* service,
const std::string& class_suffix) {
const std::string& class_suffix, bool is_server) {
std::string output;
{
StringOutputStream output_stream(&output);
@ -188,7 +331,7 @@ std::string GenerateFile(const FileDescriptor* file,
vars["package"] = php_namespace;
out.Print(vars, "namespace $package$;\n\n");
PrintService(service, class_suffix, &out);
PrintService(service, class_suffix, is_server, &out);
}
return output;
}

@ -25,7 +25,8 @@ namespace grpc_php_generator {
std::string GenerateFile(const grpc::protobuf::FileDescriptor* file,
const grpc::protobuf::ServiceDescriptor* service,
const std::string& class_suffix);
const std::string& class_suffix,
bool is_server = false);
} // namespace grpc_php_generator

@ -28,8 +28,10 @@ namespace grpc_php_generator {
inline std::string GetPHPServiceClassname(
const grpc::protobuf::ServiceDescriptor* service,
const std::string& class_suffix) {
return service->name() + (class_suffix == "" ? "Client" : class_suffix);
const std::string& class_suffix, bool is_server) {
return service->name() +
(class_suffix == "" ? (is_server ? "" : "Client") : class_suffix) +
(is_server ? "Stub" : "");
}
// ReplaceAll replaces all instances of search with replace in s.
@ -46,7 +48,7 @@ inline std::string ReplaceAll(std::string s, const std::string& search,
inline std::string GetPHPServiceFilename(
const grpc::protobuf::FileDescriptor* file,
const grpc::protobuf::ServiceDescriptor* service,
const std::string& class_suffix) {
const std::string& class_suffix, bool is_server) {
std::ostringstream oss;
if (file->options().has_php_namespace()) {
oss << ReplaceAll(file->options().php_namespace(), "\\", "/");
@ -58,8 +60,8 @@ inline std::string GetPHPServiceFilename(
<< grpc_generator::CapitalizeFirstLetter(tokens[i]);
}
}
return oss.str() + "/" + GetPHPServiceClassname(service, class_suffix) +
".php";
return oss.str() + "/" +
GetPHPServiceClassname(service, class_suffix, is_server) + ".php";
}
// Get leading or trailing comments in a string. Comment lines start with "// ".

@ -48,10 +48,13 @@ class PHPGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
std::vector<std::pair<std::string, std::string> > options;
ParseGeneratorParameter(parameter, &options);
bool generate_server = false;
std::string class_suffix;
for (size_t i = 0; i < options.size(); ++i) {
if (options[i].first == "class_suffix") {
class_suffix = options[i].second;
} else if (options[i].first == "generate_server") {
generate_server = true;
} else {
*error = "unsupported options: " + options[i].first;
return false;
@ -59,20 +62,32 @@ class PHPGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
}
for (int i = 0; i < file->service_count(); i++) {
std::string code = GenerateFile(file, file->service(i), class_suffix);
// Get output file name
std::string file_name =
GetPHPServiceFilename(file, file->service(i), class_suffix);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(file_name));
grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
GenerateService(file, file->service(i), class_suffix, false, context);
if (generate_server) {
GenerateService(file, file->service(i), class_suffix, true, context);
}
}
return true;
}
private:
void GenerateService(
const grpc::protobuf::FileDescriptor* file,
const grpc::protobuf::ServiceDescriptor* service,
const std::string& class_suffix, bool is_server,
grpc::protobuf::compiler::GeneratorContext* context) const {
std::string code = GenerateFile(file, service, class_suffix, is_server);
// Get output file name
std::string file_name =
GetPHPServiceFilename(file, service, class_suffix, is_server);
std::unique_ptr<grpc::protobuf::io::ZeroCopyOutputStream> output(
context->Open(file_name));
grpc::protobuf::io::CodedOutputStream coded_out(output.get());
coded_out.WriteRaw(code.data(), code.size());
}
};
int main(int argc, char* argv[]) {

@ -40,7 +40,7 @@ mv $output_file ./src/proto/grpc/testing/test.proto
# interop test protos
$PROTOC --proto_path=. \
--php_out=src/php/tests/interop \
--grpc_out=src/php/tests/interop \
--grpc_out=generate_server:src/php/tests/interop \
--plugin=$PLUGIN \
src/proto/grpc/testing/messages.proto \
src/proto/grpc/testing/empty.proto \
@ -53,12 +53,3 @@ mv $output_file ./src/proto/grpc/testing/empty.proto
sed 's/grpc\.testing\.EmptyMessage/grpc\.testing\.Empty/g' \
src/proto/grpc/testing/test.proto > $output_file
mv $output_file ./src/proto/grpc/testing/test.proto
# Hack for xDS interop: need this to be a separate file in the correct namespace.
# To be removed when grpc_php_plugin generates service stubs.
echo '<?php
// DO NOT EDIT
namespace Grpc\Testing;
class LoadBalancerStatsServiceStub {
}
' > ./src/php/tests/interop/Grpc/Testing/LoadBalancerStatsServiceStub.php

@ -32,135 +32,120 @@ namespace Grpc;
*/
class RpcServer extends Server
{
protected $call;
// [ <String method_full_path> => [
// 'service' => <Object service>,
// 'method' => <String method_name>,
// 'request' => <Object request>,
// ] ]
protected $paths_map;
// [ <String method_full_path> => MethodDescriptor ]
private $paths_map = [];
private function waitForNextEvent() {
private function waitForNextEvent()
{
return $this->requestCall();
}
private function loadRequest($request) {
if (!$this->call) {
throw new Exception("serverCall is not ready");
}
$event = $this->call->startBatch([
OP_RECV_MESSAGE => true,
]);
$request->clear();
$request->mergeFromString($event->message);
return $request;
}
protected function sendOkResponse($response) {
if (!$this->call) {
throw new Exception("serverCall is not ready");
}
$this->call->startBatch([
OP_SEND_INITIAL_METADATA => [],
OP_SEND_MESSAGE => ['message' =>
$response->serializeToString()],
OP_SEND_STATUS_FROM_SERVER => [
'metadata' => [],
'code' => STATUS_OK,
'details' => 'OK',
],
OP_RECV_CLOSE_ON_SERVER => true,
]);
}
/**
* Add a service to this server
*
* @param Object $service The service to be added
*/
public function handle($service) {
$rf = new \ReflectionClass($service);
// If input does not have a parent class, which should be the
// generated stub, don't proceeed. This might change in the
// future.
if (!$rf->getParentClass()) return;
// The input class name needs to match the service name
$service_name = $rf->getName();
$namespace = $rf->getParentClass()->getNamespaceName();
$prefix = "";
if ($namespace) {
$parts = explode("\\", $namespace);
foreach ($parts as $part) {
$prefix .= lcfirst($part) . ".";
}
public function handle($service)
{
$methodDescriptors = $service->getMethodDescriptors();
$exist_methods = array_intersect_key($this->paths_map, $methodDescriptors);
if (!empty($exist_methods)) {
fwrite(STDERR, "WARNING: " . 'override already registered methods: ' .
implode(', ', array_keys($exist_methods)) . PHP_EOL);
}
$base_path = "/" . $prefix . $service_name;
// Right now, assume all the methods in the class are RPC method
// implementations. Might change in the future.
$methods = $rf->getMethods();
foreach ($methods as $method) {
$method_name = $method->getName();
$full_path = $base_path . "/" . ucfirst($method_name);
$method_params = $method->getParameters();
// RPC should have exactly 1 request param
if (count($method_params) != 1) continue;
$request_param = $method_params[0];
// Method implementation must have type hint for request param
if (!$request_param->getType()) continue;
$request_type = $request_param->getType()->getName();
// $full_path needs to match the incoming event->method
// from requestCall() for us to know how to handle the request
$this->paths_map[$full_path] = [
'service' => $service,
'method' => $method_name,
'request' => new $request_type(),
];
}
$this->paths_map = array_merge($this->paths_map, $methodDescriptors);
return $this->paths_map;
}
public function run() {
public function run()
{
$this->start();
while (true) {
while (true) try {
// This blocks until the server receives a request
$event = $this->waitForNextEvent();
if (!$event) {
throw new Exception(
"Unexpected error: server->waitForNextEvent delivers"
. " an empty event");
}
if (!$event->call) {
throw new Exception(
"Unexpected error: server->waitForNextEvent delivers"
. " an event without a call");
}
$this->call = $event->call;
$full_path = $event->method;
// TODO: Can send a proper UNIMPLEMENTED response in the future
if (!array_key_exists($full_path, $this->paths_map)) continue;
$service = $this->paths_map[$full_path]['service'];
$method = $this->paths_map[$full_path]['method'];
$request = $this->paths_map[$full_path]['request'];
$request = $this->loadRequest($request);
if (!$request) {
throw new Exception("Unexpected error: fail to parse request");
}
if (!method_exists($service, $method)) {
// TODO: Can send a proper UNIMPLEMENTED response in the future
throw new Exception("Method not implemented");
$full_path = $event->method;
$context = new ServerContext($event);
$server_writer = new ServerCallWriter($event->call, $context);
if (!array_key_exists($full_path, $this->paths_map)) {
$context->setStatus(Status::unimplemented());
$server_writer->finish();
continue;
};
$method_desc = $this->paths_map[$full_path];
$server_reader = new ServerCallReader(
$event->call,
$method_desc->request_type
);
try {
$this->processCall(
$method_desc,
$server_reader,
$server_writer,
$context
);
} catch (\Exception $e) {
$context->setStatus(Status::status(
STATUS_INTERNAL,
$e->getMessage()
));
$server_writer->finish();
}
} catch (\Exception $e) {
fwrite(STDERR, "ERROR: " . $e->getMessage() . PHP_EOL);
exit(1);
}
}
// Dispatch to actual server logic
$response = $service->$method($request);
$this->sendOkResponse($response);
$this->call = null;
private function processCall(
MethodDescriptor $method_desc,
ServerCallReader $server_reader,
ServerCallWriter $server_writer,
ServerContext $context
) {
// Dispatch to actual server logic
switch ($method_desc->call_type) {
case MethodDescriptor::UNARY_CALL:
$request = $server_reader->read();
$response =
call_user_func(
array($method_desc->service, $method_desc->method_name),
$request ?? new $method_desc->request_type,
$context
);
$server_writer->finish($response);
break;
case MethodDescriptor::SERVER_STREAMING_CALL:
$request = $server_reader->read();
call_user_func(
array($method_desc->service, $method_desc->method_name),
$request ?? new $method_desc->request_type,
$server_writer,
$context
);
break;
case MethodDescriptor::CLIENT_STREAMING_CALL:
$response = call_user_func(
array($method_desc->service, $method_desc->method_name),
$server_reader,
$context
);
$server_writer->finish($response);
break;
case MethodDescriptor::BIDI_STREAMING_CALL:
call_user_func(
array($method_desc->service, $method_desc->method_name),
$server_reader,
$server_writer,
$context
);
break;
default:
throw new \Exception();
}
}
}

@ -28,44 +28,51 @@ namespace Grpc;
class ServerCallWriter
{
public function __construct($call)
public function __construct($call, $serverContext)
{
$this->call_ = $call;
$this->serverContext_ = $serverContext;
}
public function start(
array $initialMetadata,
$data = null,
array $options = []
) {
$batch = [];
$this->addSendInitialMetadataOpIfNotSent($batch, $initialMetadata);
$this->addSendInitialMetadataOpIfNotSent(
$batch,
$this->serverContext_->initialMetadata()
);
$this->addSendMessageOpIfHasData($batch, $data, $options);
$this->call_->startBatch($batch);
}
public function write(
$data,
array $options = [],
array $initialMetadata = null
array $options = []
) {
$batch = [];
$this->addSendInitialMetadataOpIfNotSent($batch, $initialMetadata);
$this->addSendInitialMetadataOpIfNotSent(
$batch,
$this->serverContext_->initialMetadata()
);
$this->addSendMessageOpIfHasData($batch, $data, $options);
$this->call_->startBatch($batch);
}
public function finish(
array $status = null,
array $initialMetadata = null,
$data = null,
array $options = []
) {
$batch = [
OP_SEND_STATUS_FROM_SERVER => $status ?? Status::ok(),
OP_SEND_STATUS_FROM_SERVER =>
$this->serverContext_->status() ?? Status::ok(),
OP_RECV_CLOSE_ON_SERVER => true,
];
$this->addSendInitialMetadataOpIfNotSent($batch, $initialMetadata);
$this->addSendInitialMetadataOpIfNotSent(
$batch,
$this->serverContext_->initialMetadata()
);
$this->addSendMessageOpIfHasData($batch, $data, $options);
$this->call_->startBatch($batch);
}
@ -98,4 +105,5 @@ class ServerCallWriter
private $call_;
private $initialMetadataSent_ = false;
private $serverContext_;
}

@ -50,5 +50,27 @@ class ServerContext
return $this->event->method;
}
public function setInitialMetadata($initialMetadata)
{
$this->initialMetadata_ = $initialMetadata;
}
public function initialMetadata()
{
return $this->initialMetadata_;
}
public function setStatus($status)
{
$this->status_ = $status;
}
public function status()
{
return $this->status_;
}
private $event;
private $initialMetadata_;
private $status_;
}

@ -1,6 +1,82 @@
<?php
// DO NOT EDIT
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A service used to obtain stats for verifying LB behavior.
*/
class LoadBalancerStatsServiceStub {
}
/**
* Gets the backend distribution for RPCs sent by a test client.
* @param \Grpc\Testing\LoadBalancerStatsRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\LoadBalancerStatsResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function GetClientStats(
\Grpc\Testing\LoadBalancerStatsRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\LoadBalancerStatsResponse {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* Gets the accumulated stats for RPCs sent by a test client.
* @param \Grpc\Testing\LoadBalancerAccumulatedStatsRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\LoadBalancerAccumulatedStatsResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function GetClientAccumulatedStats(
\Grpc\Testing\LoadBalancerAccumulatedStatsRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\LoadBalancerAccumulatedStatsResponse {
$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 [
'/grpc.testing.LoadBalancerStatsService/GetClientStats' => new \Grpc\MethodDescriptor(
$this,
'GetClientStats',
'\Grpc\Testing\LoadBalancerStatsRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.LoadBalancerStatsService/GetClientAccumulatedStats' => new \Grpc\MethodDescriptor(
$this,
'GetClientAccumulatedStats',
'\Grpc\Testing\LoadBalancerAccumulatedStatsRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -0,0 +1,80 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A service used to control reconnect server.
*/
class ReconnectServiceStub {
/**
* @param \Grpc\Testing\ReconnectParams $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Start(
\Grpc\Testing\ReconnectParams $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\ReconnectInfo for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Stop(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\ReconnectInfo {
$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 [
'/grpc.testing.ReconnectService/Start' => new \Grpc\MethodDescriptor(
$this,
'Start',
'\Grpc\Testing\ReconnectParams',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.ReconnectService/Stop' => new \Grpc\MethodDescriptor(
$this,
'Stop',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -0,0 +1,222 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A simple service to test the various types of RPCs and experiment with
* performance with various types of payload.
*/
class TestServiceStub {
/**
* One empty request followed by one empty response.
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function EmptyCall(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* One request followed by one response.
* @param \Grpc\Testing\SimpleRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\SimpleResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnaryCall(
\Grpc\Testing\SimpleRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\SimpleResponse {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* One request followed by one response. Response has cache control
* headers set such that a caching HTTP proxy (such as GFE) can
* satisfy subsequent requests.
* @param \Grpc\Testing\SimpleRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\SimpleResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function CacheableUnaryCall(
\Grpc\Testing\SimpleRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\SimpleResponse {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* One request followed by a sequence of responses (streamed download).
* The server returns the payload with client desired type and sizes.
* @param \Grpc\Testing\StreamingOutputCallRequest $request client request
* @param \Grpc\ServerCallWriter $writer write response data of \Grpc\Testing\StreamingOutputCallResponse
* @param \Grpc\ServerContext $context server request context
* @return void
*/
public function StreamingOutputCall(
\Grpc\Testing\StreamingOutputCallRequest $request,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
$writer->finish();
}
/**
* A sequence of requests followed by one response (streamed upload).
* The server returns the aggregated size of client payload as the result.
* @param \Grpc\ServerCallReader $reader read client request data of \Grpc\Testing\StreamingInputCallRequest
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\StreamingInputCallResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function StreamingInputCall(
\Grpc\ServerCallReader $reader,
\Grpc\ServerContext $context
): ?\Grpc\Testing\StreamingInputCallResponse {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* A sequence of requests with each request served by the server immediately.
* As one request could lead to multiple responses, this interface
* demonstrates the idea of full duplexing.
* @param \Grpc\ServerCallReader $reader read client request data of \Grpc\Testing\StreamingOutputCallRequest
* @param \Grpc\ServerCallWriter $writer write response data of \Grpc\Testing\StreamingOutputCallResponse
* @param \Grpc\ServerContext $context server request context
* @return void
*/
public function FullDuplexCall(
\Grpc\ServerCallReader $reader,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
$writer->finish();
}
/**
* A sequence of requests followed by a sequence of responses.
* The server buffers all the client requests and then serves them in order. A
* stream of responses are returned to the client when the server starts with
* first request.
* @param \Grpc\ServerCallReader $reader read client request data of \Grpc\Testing\StreamingOutputCallRequest
* @param \Grpc\ServerCallWriter $writer write response data of \Grpc\Testing\StreamingOutputCallResponse
* @param \Grpc\ServerContext $context server request context
* @return void
*/
public function HalfDuplexCall(
\Grpc\ServerCallReader $reader,
\Grpc\ServerCallWriter $writer,
\Grpc\ServerContext $context
): void {
$context->setStatus(\Grpc\Status::unimplemented());
$writer->finish();
}
/**
* The test server will not implement this method. It will be used
* to test the behavior when clients call unimplemented methods.
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnimplementedCall(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$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 [
'/grpc.testing.TestService/EmptyCall' => new \Grpc\MethodDescriptor(
$this,
'EmptyCall',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.TestService/UnaryCall' => new \Grpc\MethodDescriptor(
$this,
'UnaryCall',
'\Grpc\Testing\SimpleRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.TestService/CacheableUnaryCall' => new \Grpc\MethodDescriptor(
$this,
'CacheableUnaryCall',
'\Grpc\Testing\SimpleRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.TestService/StreamingOutputCall' => new \Grpc\MethodDescriptor(
$this,
'StreamingOutputCall',
'\Grpc\Testing\StreamingOutputCallRequest',
\Grpc\MethodDescriptor::SERVER_STREAMING_CALL
),
'/grpc.testing.TestService/StreamingInputCall' => new \Grpc\MethodDescriptor(
$this,
'StreamingInputCall',
'\Grpc\Testing\StreamingInputCallRequest',
\Grpc\MethodDescriptor::CLIENT_STREAMING_CALL
),
'/grpc.testing.TestService/FullDuplexCall' => new \Grpc\MethodDescriptor(
$this,
'FullDuplexCall',
'\Grpc\Testing\StreamingOutputCallRequest',
\Grpc\MethodDescriptor::BIDI_STREAMING_CALL
),
'/grpc.testing.TestService/HalfDuplexCall' => new \Grpc\MethodDescriptor(
$this,
'HalfDuplexCall',
'\Grpc\Testing\StreamingOutputCallRequest',
\Grpc\MethodDescriptor::BIDI_STREAMING_CALL
),
'/grpc.testing.TestService/UnimplementedCall' => new \Grpc\MethodDescriptor(
$this,
'UnimplementedCall',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -0,0 +1,62 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A simple service NOT implemented at servers so clients can test for
* that case.
*/
class UnimplementedServiceStub {
/**
* A call that no server should implement
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function UnimplementedCall(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$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 [
'/grpc.testing.UnimplementedService/UnimplementedCall' => new \Grpc\MethodDescriptor(
$this,
'UnimplementedCall',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -1,6 +1,61 @@
<?php
// DO NOT EDIT
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A service to dynamically update the configuration of an xDS test client.
*/
class XdsUpdateClientConfigureServiceStub {
}
/**
* Update the tes client's configuration.
* @param \Grpc\Testing\ClientConfigureRequest $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\ClientConfigureResponse for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function Configure(
\Grpc\Testing\ClientConfigureRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\ClientConfigureResponse {
$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 [
'/grpc.testing.XdsUpdateClientConfigureService/Configure' => new \Grpc\MethodDescriptor(
$this,
'Configure',
'\Grpc\Testing\ClientConfigureRequest',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -0,0 +1,80 @@
<?php
// GENERATED CODE -- DO NOT EDIT!
// Original file comments:
// Copyright 2015-2016 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
//
namespace Grpc\Testing;
/**
* A service to remotely control health status of an xDS test server.
*/
class XdsUpdateHealthServiceStub {
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SetServing(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$context->setStatus(\Grpc\Status::unimplemented());
return null;
}
/**
* @param \Grpc\Testing\EmptyMessage $request client request
* @param \Grpc\ServerContext $context server request context
* @return \Grpc\Testing\EmptyMessage for response data, null if if error occured
* initial metadata (if any) and status (if not ok) should be set to $context
*/
public function SetNotServing(
\Grpc\Testing\EmptyMessage $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\EmptyMessage {
$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 [
'/grpc.testing.XdsUpdateHealthService/SetServing' => new \Grpc\MethodDescriptor(
$this,
'SetServing',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
'/grpc.testing.XdsUpdateHealthService/SetNotServing' => new \Grpc\MethodDescriptor(
$this,
'SetNotServing',
'\Grpc\Testing\EmptyMessage',
\Grpc\MethodDescriptor::UNARY_CALL
),
];
}
}

@ -28,7 +28,10 @@ require_once $autoload_path;
class XdsUpdateClientConfigureService
extends \Grpc\Testing\XdsUpdateClientConfigureServiceStub
{
function configure(\Grpc\Testing\ClientConfigureRequest $request) {
function configure(
\Grpc\Testing\ClientConfigureRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\ClientConfigureResponse {
$rpc_types = $request->getTypes();
$all_metadata = $request->getMetadata();
$rpcs_to_send = [];
@ -75,7 +78,10 @@ class XdsUpdateClientConfigureService
class LoadBalancerStatsService
extends \Grpc\Testing\LoadBalancerStatsServiceStub
{
function getClientStats(\Grpc\Testing\LoadBalancerStatsRequest $request) {
function getClientStats(
\Grpc\Testing\LoadBalancerStatsRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\LoadBalancerStatsResponse {
$num_rpcs = $request->getNumRpcs();
$timeout_sec = $request->getTimeoutSec();
$rpcs_by_method = [];
@ -155,8 +161,10 @@ class LoadBalancerStatsService
return $response;
}
function getClientAccumulatedStats(
\Grpc\Testing\LoadBalancerAccumulatedStatsRequest $request) {
function GetClientAccumulatedStats(
\Grpc\Testing\LoadBalancerAccumulatedStatsRequest $request,
\Grpc\ServerContext $context
): ?\Grpc\Testing\LoadBalancerAccumulatedStatsResponse {
global $client_thread;
$response = new Grpc\Testing\LoadBalancerAccumulatedStatsResponse();
$response->setNumRpcsStartedByMethod(

@ -0,0 +1,85 @@
<?php
/*
*
* Copyright 2015 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallReader.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallWriter.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/Status.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/MethodDescriptor.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/RpcServer.php');
class RpcServerTest extends \PHPUnit\Framework\TestCase
{
public function setUp(): void
{
$this->server = new \Grpc\RpcServer();
$this->mockService = $this->getMockBuilder(stdClass::class)
->setMethods(['getMethodDescriptors', 'hello'])
->getMock();
}
public function testHandleServices()
{
$helloMethodDescriptor = new \Grpc\MethodDescriptor(
$this->mockService,
'hello',
'String',
\Grpc\MethodDescriptor::UNARY_CALL
);
$this->mockService->expects($this->once())
->method('getMethodDescriptors')
->with()
->will($this->returnValue([
'/test/hello' => $helloMethodDescriptor
]));
$pathMap = $this->server->handle($this->mockService);
$this->assertEquals($pathMap, [
'/test/hello' => $helloMethodDescriptor
]);
$mockService2 = $this->getMockBuilder(stdClass::class)
->setMethods(['getMethodDescriptors', 'hello', 'bye'])
->getMock();
$helloMethodDescriptor2 = new \Grpc\MethodDescriptor(
$this->mockService,
'hello',
'Number',
\Grpc\MethodDescriptor::UNARY_CALL
);
$byeMethodDescritor = new \Grpc\MethodDescriptor(
$this->mockService,
'bye',
'String',
\Grpc\MethodDescriptor::UNARY_CALL
);
$mockService2->expects($this->once())
->method('getMethodDescriptors')
->with()
->will($this->returnValue([
'/test/hello' => $helloMethodDescriptor2,
'/test/bye' => $byeMethodDescritor
]));
$pathMap = $this->server->handle($mockService2);
$this->assertEquals($pathMap, [
'/test/hello' => $helloMethodDescriptor2,
'/test/bye' => $byeMethodDescritor
]);
}
}

@ -20,6 +20,7 @@
require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallReader.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerCallWriter.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/Status.php');
require_once(dirname(__FILE__) . '/../../lib/Grpc/ServerContext.php');
class StartBatchEvent
{
@ -62,6 +63,7 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
$this->mockCall = $this->getMockBuilder(stdClass::class)
->setMethods(['startBatch'])
->getMock();
$this->serverContext = new \Grpc\ServerContext($this->mockCall);
}
public function newStringMessage(string $value = 'a string')
@ -97,8 +99,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_INITIAL_METADATA => [],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->start([]);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata([]);
$serverCallWriter->start();
}
public function testStartWithMetadata()
@ -111,8 +117,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_INITIAL_METADATA => $metadata,
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->start($metadata);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$serverCallWriter->start();
return $serverCallWriter;
}
@ -128,8 +138,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->start($metadata, $message);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$serverCallWriter->start($message);
}
public function testWriteStartWithMessageAndOptions()
@ -147,8 +161,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->start($metadata, $message, ['flags' => 0x02]);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$serverCallWriter->start($message, ['flags' => 0x02]);
}
public function testWriteDataOnly()
@ -162,7 +180,10 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$serverCallWriter->write($message);
}
@ -180,7 +201,10 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$serverCallWriter->write($message, ['flags' => 0x02]);
}
@ -196,8 +220,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_MESSAGE => ['message' => $message->serializeToString()],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->write($message, [], $metadata);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$serverCallWriter->write($message, []);
}
public function testFinish()
@ -216,8 +244,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_SEND_INITIAL_METADATA => [],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->finish($status);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setStatus($status);
$serverCallWriter->finish();
}
public function testFinishWithMetadataAndMessage()
@ -238,8 +270,13 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
],
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->finish($status, $metadata, $message, ['flags' => 0x02]);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$this->serverContext->setStatus($status);
$serverCallWriter->finish($message, ['flags' => 0x02]);
}
public function testStartWriteFinish()
@ -274,8 +311,12 @@ class ServerCallTest extends \PHPUnit\Framework\TestCase
\Grpc\OP_RECV_CLOSE_ON_SERVER => true,
]));
$serverCallWriter = new \Grpc\ServerCallWriter($this->mockCall);
$serverCallWriter->start($metadata);
$serverCallWriter = new \Grpc\ServerCallWriter(
$this->mockCall,
$this->serverContext
);
$this->serverContext->setInitialMetadata($metadata);
$serverCallWriter->start();
$serverCallWriter->write($message1, [], $metadata2 /* should not send */);
$serverCallWriter->write($message2, ['flags' => 0x02]);
$serverCallWriter->finish();

Loading…
Cancel
Save