-
Notifications
You must be signed in to change notification settings - Fork 17
pure php grpc #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| { | ||
| "name": "grpc/grpc-demo", | ||
| "description": "gRPC example for PHP", | ||
| "require": { | ||
| "google/protobuf": "^v3.3.0" | ||
| }, | ||
| "autoload": { | ||
| "psr-4": { | ||
| "": "./", | ||
| "Grpc\\": "../grpc/src/lib" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package grpc.gateway.testing; | ||
|
|
||
| message Empty { | ||
| } | ||
|
|
||
| message EchoRequest { | ||
| string message = 1; | ||
| } | ||
|
|
||
| message EchoResponse { | ||
| string message = 1; | ||
| int32 message_count = 2; | ||
| } | ||
|
|
||
| // Request type for server side streaming echo. | ||
| message ServerStreamingEchoRequest { | ||
| // Message string for server streaming request. | ||
| string message = 1; | ||
|
|
||
| // The total number of messages to be generated before the server | ||
| // closes the stream; default is 10. | ||
| int32 message_count = 2; | ||
|
|
||
| // The interval (ms) between two server messages. The server implementation | ||
| // may enforce some minimum interval (e.g. 100ms) to avoid message overflow. | ||
| int32 message_interval = 3; | ||
| } | ||
|
|
||
| // Response type for server streaming response. | ||
| message ServerStreamingEchoResponse { | ||
| // Response message. | ||
| string message = 1; | ||
| } | ||
|
|
||
| // Request type for client side streaming echo. | ||
| message ClientStreamingEchoRequest { | ||
| // A special value "" indicates that there's no further messages. | ||
| string message = 1; | ||
| } | ||
|
|
||
| // Response type for client side streaming echo. | ||
| message ClientStreamingEchoResponse { | ||
| // Total number of client messages that have been received. | ||
| int32 message_count = 1; | ||
| } | ||
|
|
||
| // A simple echo service. | ||
| service EchoService { | ||
| // One request followed by one response | ||
| // The server returns the client message as-is. | ||
| rpc Echo(EchoRequest) returns (EchoResponse); | ||
|
|
||
| // Sends back abort status. | ||
| rpc EchoAbort(EchoRequest) returns (EchoResponse) { | ||
| }; | ||
|
|
||
| // One empty request, ZERO processing, followed by one empty response | ||
| // (minimum effort to do message serialization). | ||
| rpc NoOp(Empty) returns (Empty); | ||
|
|
||
| // One request followed by a sequence of responses (streamed download). | ||
| // The server will return the same client message repeatedly. | ||
| rpc ServerStreamingEcho(ServerStreamingEchoRequest) | ||
| returns (stream ServerStreamingEchoResponse); | ||
|
|
||
| // One request followed by a sequence of responses (streamed download). | ||
| // The server abort directly. | ||
| rpc ServerStreamingEchoAbort(ServerStreamingEchoRequest) | ||
| returns (stream ServerStreamingEchoResponse) { | ||
| } | ||
|
|
||
| // A sequence of requests followed by one response (streamed upload). | ||
| // The server returns the total number of messages as the result. | ||
| rpc ClientStreamingEcho(stream ClientStreamingEchoRequest) | ||
| returns (ClientStreamingEchoResponse); | ||
|
|
||
| // A sequence of requests with each message echoed by the server immediately. | ||
| // The server returns the same client messages in order. | ||
| // E.g. this is how the speech API works. | ||
| rpc FullDuplexEcho(stream EchoRequest) returns (stream EchoResponse); | ||
|
|
||
| // A sequence of requests followed by a sequence of responses. | ||
| // The server buffers all the client messages and then returns the same | ||
| // client messages one by one after the client half-closes the stream. | ||
| // This is how an image recognition API may work. | ||
| rpc HalfDuplexEcho(stream EchoRequest) returns (stream EchoResponse); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| #!/bin/bash | ||
| protoc --proto_path=./ --php_out=./ --grpc_out=./ \ | ||
| --plugin=protoc-gen-grpc=/usr/local/bin/grpc_php_plugin ./my_echo.proto | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <?php | ||
| require dirname(__FILE__).'/vendor/autoload.php'; | ||
|
|
||
| $client = new \Grpc\Gateway\Testing\EchoServiceClient('localhost:9091', []); | ||
|
||
|
|
||
| $echo_request = new \Grpc\Gateway\Testing\EchoRequest(); | ||
| $message = "Hello"; | ||
| $echo_request->setMessage($message); | ||
| $call_echo = $client->Echo($echo_request); | ||
|
|
||
| $streamRequest = new \Grpc\Gateway\Testing\ServerStreamingEchoRequest(); | ||
| $streamRequest->setMessage($message); | ||
| $streamRequest->setMessageCount(3); | ||
| $streamRequest->setMessageInterval(500); | ||
| $call_stream_echo = $client->ServerStreamingEcho($streamRequest); | ||
|
|
||
| // Get response | ||
| $streamResponse = $call_stream_echo->responses($streamRequest); | ||
| list($reply, $status) = $call_echo->wait(); | ||
| // Print response | ||
| echo "Echo response:".PHP_EOL.$reply->getMessage().PHP_EOL; | ||
| echo "StreamEcho response:".PHP_EOL; | ||
| foreach ($streamResponse as $feature) { | ||
| echo $feature->getMessage().PHP_EOL; | ||
| } | ||
| $client->close(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
|
||
| "name": "grpc/grpc", | ||
| "type": "library", | ||
| "description": "gRPC library for PHP", | ||
| "keywords": ["rpc"], | ||
| "homepage": "https://grpc.io", | ||
| "license": "Apache-2.0", | ||
| "version": "1.6.0", | ||
| "require": { | ||
| "php": ">=5.5.0" | ||
| }, | ||
| "require-dev": { | ||
| "google/auth": "v0.9" | ||
| }, | ||
| "suggest": { | ||
| "ext-protobuf": "For better performance, install the protobuf C extension.", | ||
| "google/protobuf": "To get started using grpc quickly, install the native protobuf library." | ||
| }, | ||
| "autoload": { | ||
| "psr-4": { | ||
| "Grpc\\": "src/lib/" | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,175 @@ | ||
| <?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. | ||
| * | ||
| */ | ||
|
|
||
| namespace Grpc; | ||
|
|
||
| /** | ||
| * Class AbstractCall. | ||
| * @package Grpc | ||
| */ | ||
| abstract class AbstractCall | ||
| { | ||
| /** | ||
| * @var Call | ||
| */ | ||
| //protected $call; | ||
| protected $deserialize; | ||
| protected $metadata; | ||
| protected $trailing_metadata; | ||
| protected $channel; | ||
| protected $ch; | ||
|
|
||
| /** | ||
| * Create a new Call wrapper object. | ||
| * | ||
| * @param resource $channel The channel to communicate on | ||
| * @param string $method The method to call on the | ||
| * remote server | ||
| * @param callback $deserialize A callback function to deserialize | ||
| * the response | ||
| * @param array $options Call options (optional) | ||
| */ | ||
| public function __construct($channel, | ||
| $method, | ||
| $deserialize, | ||
| array $options = []) | ||
| { | ||
| // TODO: check Timeout,etc from $options | ||
| // TODO: call credentials? | ||
| $this->ch = curl_init(); | ||
| $headers[] = 'custom-header-1: value1'; | ||
| $headers[] = 'Content-Type: application/grpc-web-text'; | ||
| $headers[] = 'Accept: application/grpc-web-text'; | ||
|
|
||
| curl_setopt($this->ch, CURLOPT_POST, 1); | ||
| curl_setopt($this->ch, CURLOPT_URL, $method); | ||
| curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); | ||
| curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true); | ||
|
|
||
| $this->channel = $channel; | ||
| $this->deserialize = $deserialize; | ||
| $this->metadata = null; | ||
| $this->trailing_metadata = null; | ||
| } | ||
|
|
||
| /** | ||
| * @param mixed $argument The data to decode | ||
| * @return string Base64 decoded massage | ||
| */ | ||
| public function _base64encode($argument) { | ||
| $serialized_data = $argument->serializeToString(); | ||
| $len = strlen($serialized_data); | ||
| $bytesArray = [0, 0, 0, 0, 0]; | ||
| for ($i = 4; $i >= 1; $i--) { | ||
| $bytesArray[$i] = ($len % 256); | ||
| $len = $len >> 8; | ||
| } | ||
| $serialized_data_byte = unpack('C*', $serialized_data); | ||
| $argument_data_byte = array_merge($bytesArray, $serialized_data_byte); | ||
| $argument_data_string = implode(array_map("chr", $argument_data_byte)); | ||
| return base64_encode($argument_data_string); | ||
| } | ||
|
|
||
| /** | ||
| * @return mixed The metadata sent by the server | ||
| */ | ||
| public function getMetadata() | ||
| { | ||
| } | ||
|
|
||
| /** | ||
| * @return mixed The trailing metadata sent by the server | ||
| */ | ||
| public function getTrailingMetadata() | ||
| { | ||
| } | ||
|
|
||
| /** | ||
| * @return string The URI of the endpoint | ||
| */ | ||
| public function getPeer() | ||
| { | ||
| } | ||
|
|
||
| /** | ||
| * Cancels the call. | ||
| */ | ||
| public function cancel() | ||
| { | ||
| } | ||
|
|
||
| /** | ||
| * Serialize a message to the protobuf binary format. | ||
| * | ||
| * @param mixed $data The Protobuf message | ||
| * | ||
| * @return string The protobuf binary format | ||
| */ | ||
| protected function _serializeMessage($data) | ||
| { | ||
| // Proto3 implementation | ||
| if (method_exists($data, 'encode')) { | ||
| return $data->encode(); | ||
| } elseif (method_exists($data, 'serializeToString')) { | ||
| return $data->serializeToString(); | ||
| } | ||
|
|
||
| // Protobuf-PHP implementation | ||
| return $data->serialize(); | ||
| } | ||
|
|
||
| /** | ||
| * Deserialize a response value to an object. | ||
| * | ||
| * @param string $value The binary value to deserialize | ||
| * | ||
| * @return mixed The deserialized value | ||
| */ | ||
| protected function _deserializeResponse($value) | ||
| { | ||
| if ($value === null) { | ||
| return; | ||
| } | ||
|
|
||
| // Proto3 implementation | ||
| if (is_array($this->deserialize)) { | ||
| list($className, $deserializeFunc) = $this->deserialize; | ||
| $obj = new $className(); | ||
| if (method_exists($obj, $deserializeFunc)) { | ||
| $obj->$deserializeFunc($value); | ||
| } else { | ||
| $obj->mergeFromString($value); | ||
| } | ||
|
|
||
| return $obj; | ||
| } | ||
|
|
||
| // Protobuf-PHP implementation | ||
| return call_user_func($this->deserialize, $value); | ||
| } | ||
|
|
||
| /** | ||
| * Set the CallCredentials for the underlying Call. | ||
| * | ||
| * @param CallCredentials $call_credentials The CallCredentials object | ||
| */ | ||
| public function setCallCredentials($call_credentials) | ||
| { | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's skip the example code for now. As we probably want to use the same proto defined in grpc report instead of using echo.prot here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All example related files are removed.