PHP hello world example first draft
This commit is contained in:
parent
db7f5226d5
commit
f8401a757c
|
|
@ -304,7 +304,7 @@ implementation available from the network.
|
|||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
// Use stderr here since the logger may has been reset by its JVM shutdown hook.
|
||||
// Use stderr here since the logger may have been reset by its JVM shutdown hook.
|
||||
System.err.println("*** shutting down gRPC server since JVM is shutting down");
|
||||
HelloWorldServer.this.stop();
|
||||
System.err.println("*** server shut down");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Grpc.Tools" version="0.5.0" />
|
||||
</packages>
|
||||
|
|
@ -1,37 +1,42 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = Greeter\Greeter.csproj
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greeter", "Greeter\Greeter.csproj", "{724DFC8C-4B57-4C3F-811C-0463BE2A2829}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{A7706C84-92D2-4B7A-B779-76B64D2950EC}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{ACCF4597-3748-4117-8633-1CB767F8CCC3}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{FF1EBE95-F20D-4C27-8A61-D0125F3C8152}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.nuget\packages.config = .nuget\packages.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{724DFC8C-4B57-4C3F-811C-0463BE2A2829}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A7706C84-92D2-4B7A-B779-76B64D2950EC}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{ACCF4597-3748-4117-8633-1CB767F8CCC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(MonoDevelopProperties) = preSolution
|
||||
StartupItem = Greeter\Greeter.csproj
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Grpc.Tools" version="0.5.0" />
|
||||
</packages>
|
||||
|
|
@ -26,9 +26,11 @@ $ git clone https://github.com/google/grpc-common.git
|
|||
All the files for this tutorial are in the directory `grpc-common/csharp/route_guide`.
|
||||
Open the solution `grpc-common/csharp/route_guide/RouteGuide.sln` from Visual Studio (or Monodevelop on Linux).
|
||||
|
||||
You also should have the relevant tools installed to generate the server and client interface code.
|
||||
On Windows, you should not need to do anything besides opening the solution. All the needed dependencies will be restored
|
||||
for you automatically by the `Grpc` NuGet package upon building the solution.
|
||||
|
||||
**TODO: more on how to install protoc**
|
||||
On Linux (or MacOS), you will first need to install protobuf and gRPC C Core using Linuxbrew (or Homebrew) tool in order to be
|
||||
able to generate the server and client interface code and run the examples. Follow the instructions for [Linux](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono) or [MacOS](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono).
|
||||
|
||||
## Defining the service
|
||||
|
||||
|
|
@ -90,19 +92,25 @@ message Point {
|
|||
|
||||
Next we need to generate the gRPC client and server interfaces from our .proto service definition. We do this using the protocol buffer compiler `protoc` with a special gRPC C# plugin.
|
||||
|
||||
If you want to run this yourself, make sure you've installed protoc and followed the gRPC C# plugin [installation instructions](https://github.com/grpc/grpc/blob/master/INSTALL) first.
|
||||
|
||||
**TODO: more on how to install protoc and grpc_csharp_plugin**
|
||||
If you want to run this yourself, make sure you've installed protoc and gRPC C# plugin. The instructions vary based on your OS:
|
||||
- For Windows, the `Grpc.Tools` NuGet package contains the binaries you will need to generate the code.
|
||||
- For Linux, make sure you've [installed gRPC C Core using Linuxbrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-linux-mono)
|
||||
- For MacOS, make sure you've [installed gRPC C Core using Homebrew](https://github.com/grpc/grpc/tree/master/src/csharp#usage-macos-mono)
|
||||
|
||||
Once that's done, the following command can be used to generate the C# code.
|
||||
|
||||
To generate the code on Windows, we use `protoc.exe` and `grpc_csharp_plugin.exe` binaries that are shipped with the `Grpc.Tools` NuGet package under the `tools` directory.
|
||||
Normally you would need to add the `Grpc.Tools` package to the solution yourself, but in this tutorial it has been already done for you. Following command should be run from the `csharp/route_guide` directory:
|
||||
```
|
||||
> packages\Grpc.Tools.0.5.0\tools\protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=packages\Grpc.Tools.0.5.0\tools\grpc_csharp_plugin.exe RouteGuide/protos/route_guide.proto
|
||||
```
|
||||
|
||||
On Linux/MacOS, we rely on `protoc` and `grpc_csharp_plugin` being installed by Linuxbrew/Homebrew. Run this command from the route_guide directory:
|
||||
```shell
|
||||
$ protoc -I RouteGuide/protos --csharp_out=RouteGuide --grpc_out=RouteGuide --plugin=protoc-gen-grpc=`which grpc_csharp_plugin` RouteGuide/protos/route_guide.proto
|
||||
```
|
||||
|
||||
**TODO: command for windows**
|
||||
|
||||
Running this command regenerates the following files in the RouteGuide directory:
|
||||
Running one of the previous commands regenerates the following files in the RouteGuide directory:
|
||||
- `RouteGuide/RouteGuide.cs` defines a namespace `examples`
|
||||
- This contains all the protocol buffer code to populate, serialize, and retrieve our request and response message types
|
||||
- `RouteGuide/RouteGuideGrpc.cs`, provides stub and service classes
|
||||
|
|
@ -130,6 +138,8 @@ As you can see, our server has a `RouteGuideImpl` class that implements the gene
|
|||
public class RouteGuideImpl : RouteGuide.IRouteGuide
|
||||
```
|
||||
|
||||
#### Simple RPC
|
||||
|
||||
`RouteGuideImpl` implements all our service methods. Let's look at the simplest type first, `GetFeature`, which just gets a `Point` from the client and returns the corresponding feature information from its database in a `Feature`.
|
||||
|
||||
```csharp
|
||||
|
|
@ -143,6 +153,8 @@ The method is passed a context for the RPC (which is empty in the alpha release)
|
|||
implementation, the method returns `Task<Feature>` rather than just `Feature`. You are free to perform your computations synchronously and return
|
||||
the result once you've finished, just as we do in the example.
|
||||
|
||||
#### Server-side streaming RPC
|
||||
|
||||
Now let's look at something a bit more complicated - a streaming RPC. `ListFeatures` is a server-side streaming RPC, so we need to send back multiple `Feature` protocol buffers to our client.
|
||||
|
||||
```csharp
|
||||
|
|
@ -174,7 +186,9 @@ Now let's look at something a bit more complicated - a streaming RPC. `ListFeatu
|
|||
|
||||
As you can see, here the request object is a `Rectangle` in which our client wants to find `Feature`s, but instead of returning a simple response we need to write responses to an asynchronous stream `IServerStreamWriter` using async method `WriteAsync`.
|
||||
|
||||
Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using async method `MoveNext` and property `Current`.
|
||||
#### Client-side streaming RPC
|
||||
|
||||
Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumerator](https://github.com/Reactive-Extensions/Rx.NET/blob/master/Ix.NET/Source/System.Interactive.Async/IAsyncEnumerator.cs), to read the stream of requests using the async method `MoveNext` and the `Current` property.
|
||||
|
||||
```csharp
|
||||
public async Task<RouteSummary> RecordRoute(Grpc.Core.ServerCallContext context,
|
||||
|
|
@ -208,6 +222,9 @@ Similarly, the client-side streaming method `RecordRoute` uses an [IAsyncEnumera
|
|||
.SetElapsedTime((int) (stopwatch.ElapsedMilliseconds / 1000)).Build();
|
||||
}
|
||||
```
|
||||
|
||||
#### Bidirectional streaming RPC
|
||||
|
||||
Finally, let's look at our bidirectional streaming RPC `RouteChat`.
|
||||
|
||||
```csharp
|
||||
|
|
@ -238,7 +255,7 @@ Finally, let's look at our bidirectional streaming RPC `RouteChat`.
|
|||
}
|
||||
```
|
||||
|
||||
Here the method receives both `requestStream` and `responseStream` as an argument. Reading the requests is done in a same way as in the `RecordRoute` example. Writing the responses is done the same way as in the `ListFeatures` example.
|
||||
Here the method receives both `requestStream` and `responseStream` arguments. Reading the requests is done the same way as in the client-side streaming method `RecordRoute`. Writing the responses is done the same way as in the server-side streaming method `ListFeatures`.
|
||||
|
||||
### Starting the server
|
||||
|
||||
|
|
@ -264,7 +281,7 @@ As you can see, we build and start our server using `Grpc.Core.Server` class. To
|
|||
|
||||
1. Create an instance of `Grpc.Core.Server`.
|
||||
1. Create an instance of our service implementation class `RouteGuideImpl`.
|
||||
3. Register our service implementation with the server using method `AddServiceDefinition` and the generated method `RouteGuide.BindService`.
|
||||
3. Register our service implementation with the server using the `AddServiceDefinition` method and the generated method `RouteGuide.BindService`.
|
||||
2. Specify the address and port we want to use to listen for client requests using the `AddListeningPort` method.
|
||||
4. Call `Start` on the server instance to start an RPC server for our service.
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGu
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{2F6B184B-A576-4F21-AF2E-27E73D1FC96E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.nuget\packages.config = .nuget\packages.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Google.ProtocolBuffers" version="2.4.1.555" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0" targetFramework="net45" />
|
||||
<package id="Grpc" version="0.5.0.1" targetFramework="net45" />
|
||||
<package id="Grpc.Core" version="0.5.0" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.openssl.redist" version="1.0.2.2" targetFramework="net45" />
|
||||
<package id="grpc.dependencies.zlib.redist" version="1.2.8.9" targetFramework="net45" />
|
||||
|
|
|
|||
|
|
@ -101,6 +101,19 @@ creds = GRPC::Core::Credentials.new(load_certs) # load_certs typically loads a
|
|||
stub = Helloworld::Greeter::Stub.new('localhost:50051', creds: creds)
|
||||
```
|
||||
|
||||
###SSL/TLS for server authentication and encryption (C#)
|
||||
```csharp
|
||||
// Base case - No encryption
|
||||
var channel = new Channel("localhost:50051");
|
||||
var client = new Greeter.GreeterClient(channel);
|
||||
...
|
||||
|
||||
// With server authentication SSL/TLS
|
||||
var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
|
||||
var channel = new Channel("localhost:50051", credentials);
|
||||
var client = new Greeter.GreeterClient(channel);
|
||||
```
|
||||
|
||||
###Authenticating with Google (Ruby)
|
||||
```ruby
|
||||
# Base case - No encryption/authorization
|
||||
|
|
@ -138,3 +151,26 @@ var scope = 'https://www.googleapis.com/auth/grpc-testing';
|
|||
grpc.getGoogleAuthDelegate(auth));
|
||||
});
|
||||
```
|
||||
|
||||
###Authenticating with Google (C#)
|
||||
```csharp
|
||||
// Base case - No encryption/authorization
|
||||
var channel = new Channel("localhost:50051");
|
||||
var client = new Greeter.GreeterClient(channel);
|
||||
...
|
||||
|
||||
// Authenticating with Google
|
||||
using Grpc.Auth; // from Grpc.Auth NuGet package
|
||||
...
|
||||
var credentials = new SslCredentials(File.ReadAllText("ca.pem")); // Load a CA file
|
||||
var channel = new Channel("localhost:50051", credentials);
|
||||
|
||||
string scope = "https://www.googleapis.com/auth/grpc-testing";
|
||||
var authorization = GoogleCredential.GetApplicationDefault();
|
||||
if (authorization.IsCreateScopedRequired)
|
||||
{
|
||||
authorization = credential.CreateScoped(new[] { scope });
|
||||
}
|
||||
var client = new Greeter.GreeterClient(channel,
|
||||
new StubConfiguration(OAuth2InterceptorFactory.Create(credential)));
|
||||
```
|
||||
|
|
|
|||
|
|
@ -4,25 +4,23 @@ gRPC in 3 minutes (Node.js)
|
|||
PREREQUISITES
|
||||
-------------
|
||||
|
||||
This requires Node 10.x or greater.
|
||||
- `node`: This requires Node 10.x or greater.
|
||||
- [homebrew][] on Mac OS X, [linuxbrew][] on Linux. These simplify the installation of the gRPC C core.
|
||||
|
||||
INSTALL
|
||||
-------
|
||||
- On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][]. Run the following command to install gRPC Node.js.
|
||||
|
||||
```sh
|
||||
$ curl -fsSL https://goo.gl/getgrpc | bash -s nodejs
|
||||
```
|
||||
This will download and run the [gRPC install script][], then install the latest version of gRPC Nodejs npm package.
|
||||
- Clone this repository
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/grpc/grpc-common.git
|
||||
```
|
||||
|
||||
- Download the grpc debian packages from the [latest grpc release](https://github.com/grpc/grpc/releases) and install them.
|
||||
- Later, it will possible to install them directly using `apt-get install`
|
||||
```sh
|
||||
$ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc_0.5.0_amd64.deb
|
||||
$ wget https://github.com/grpc/grpc/releases/download/release-0_5_0/libgrpc-dev_0.5.0_amd64.deb
|
||||
$ sudo dpkg -i libgrpc_0.5.0_amd64.deb libgrpc-dev_0.5.0_amd64.deb
|
||||
```
|
||||
|
||||
- Install this package's dependencies
|
||||
|
||||
```sh
|
||||
|
|
@ -49,11 +47,14 @@ TRY IT!
|
|||
|
||||
NOTE
|
||||
----
|
||||
|
||||
This directory has a copy of `helloworld.proto` because it currently depends on
|
||||
some Protocol Buffer 2.0 syntax that is deprecated in Protocol Buffer 3.0.
|
||||
|
||||
TUTORIAL
|
||||
--------
|
||||
You can find a more detailed tutorial in [gRPC Basics: Node.js][]
|
||||
|
||||
You can find a more detailed tutorial in [gRPC Basics: Node.js](https://github.com/grpc/grpc-common/blob/master/node/route_guide/README.md).
|
||||
[homebrew]:http://brew.sh
|
||||
[linuxbrew]:https://github.com/Homebrew/linuxbrew#installation
|
||||
[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
|
||||
[gRPC Basics: Node.js]:https://github.com/grpc/grpc-common/blob/master/node/route_guide/README.md
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"version": "0.5.0",
|
||||
"dependencies": {
|
||||
"async": "^0.9.0",
|
||||
"grpc": "~0.5.0",
|
||||
"grpc": "~0.9.0",
|
||||
"minimist": "^1.1.0",
|
||||
"underscore": "^1.8.2"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
composer.lock
|
||||
vendor/
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
gRPC in 3 minutes (PHP)
|
||||
===========================
|
||||
|
||||
PREREQUISITES
|
||||
-------------
|
||||
|
||||
This requires PHP 5.5 or greater.
|
||||
|
||||
INSTALL
|
||||
-------
|
||||
|
||||
- Clone this repository
|
||||
|
||||
```sh
|
||||
$ git clone https://github.com/grpc/grpc-common.git
|
||||
```
|
||||
|
||||
- Install Protobuf-PHP
|
||||
|
||||
```
|
||||
$ git clone https://github.com/murgatroid99/Protobuf-PHP.git
|
||||
$ cd Protobuf-PHP
|
||||
$ rake pear:package version=1.0
|
||||
$ pear install Protobuf-1.0.tgz
|
||||
```
|
||||
|
||||
- Install composer
|
||||
|
||||
```
|
||||
$ cd grpc-common/php
|
||||
$ curl -sS https://getcomposer.org/installer | php
|
||||
```
|
||||
|
||||
- (Coming soon) Download the gRPC PECL extension
|
||||
|
||||
```
|
||||
Coming soon
|
||||
```
|
||||
|
||||
- (Temporary workaround) Compile gRPC extension from source
|
||||
|
||||
```
|
||||
$ git clone https://github.com/grpc/grpc.git
|
||||
$ cd grpc
|
||||
$ git checkout --track origin/release-0_9
|
||||
$ git pull --recurse-submodules && git submodule update --init --recursive
|
||||
$ cd third_party/protobuf
|
||||
$ ./autogen.sh && ./configure --prefix=/usr && make && make install
|
||||
$ cd ../..
|
||||
$ make && make install
|
||||
$ cd src/php/ext/grpc
|
||||
$ phpize && ./configure && make && make install
|
||||
```
|
||||
|
||||
|
||||
TRY IT!
|
||||
-------
|
||||
|
||||
- Run the server
|
||||
|
||||
Please follow the instruction in [Node](https://github.com/grpc/grpc-common/tree/master/node) to run the server
|
||||
```
|
||||
$ cd grpc-common/node
|
||||
$ nodejs greeter_server.js
|
||||
```
|
||||
|
||||
- Run the client
|
||||
|
||||
```
|
||||
$ cd grpc-common/php
|
||||
$ php composer.phar install
|
||||
$ php -d extension=grpc.so greeter_client.php
|
||||
```
|
||||
|
||||
NOTE
|
||||
----
|
||||
|
||||
This directory has a copy of `helloworld.proto` because it currently depends on
|
||||
some Protocol Buffer 2.0 syntax. There is no proto3 support for PHP yet.
|
||||
|
||||
TUTORIAL
|
||||
--------
|
||||
|
||||
Coming soon
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "grpc/grpc-demo",
|
||||
"description": "gRPC example for PHP",
|
||||
"minimum-stability": "dev",
|
||||
"require": {
|
||||
"php": ">=5.5.0",
|
||||
"grpc/grpc": "dev-master"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/*
|
||||
*
|
||||
* Copyright 2015, Google Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of Google Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
require 'DrSlump/Protobuf.php';
|
||||
\DrSlump\Protobuf::autoload();
|
||||
require 'vendor/autoload.php';
|
||||
require 'helloworld.php';
|
||||
|
||||
function greet($name) {
|
||||
$client = new helloworld\GreeterClient(
|
||||
new Grpc\BaseStub('localhost:50051', []));
|
||||
$request = new helloworld\HelloRequest();
|
||||
$request->setName($name);
|
||||
list($reply, $status) = $client->SayHello($request)->wait();
|
||||
$message = $reply->getMessage();
|
||||
return $message;
|
||||
}
|
||||
|
||||
$name = !empty($argv[1]) ? $argv[1] : 'world';
|
||||
print(greet($name)."\n");
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
// DO NOT EDIT! Generated by Protobuf-PHP protoc plugin 1.0
|
||||
// Source: helloworld.proto
|
||||
// Date: 2015-05-29 21:39:19
|
||||
|
||||
namespace helloworld {
|
||||
|
||||
class HelloRequest extends \DrSlump\Protobuf\Message {
|
||||
|
||||
/** @var string */
|
||||
public $name = null;
|
||||
|
||||
|
||||
/** @var \Closure[] */
|
||||
protected static $__extensions = array();
|
||||
|
||||
public static function descriptor()
|
||||
{
|
||||
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
|
||||
|
||||
// OPTIONAL STRING name = 1
|
||||
$f = new \DrSlump\Protobuf\Field();
|
||||
$f->number = 1;
|
||||
$f->name = "name";
|
||||
$f->type = \DrSlump\Protobuf::TYPE_STRING;
|
||||
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
|
||||
$descriptor->addField($f);
|
||||
|
||||
foreach (self::$__extensions as $cb) {
|
||||
$descriptor->addField($cb(), true);
|
||||
}
|
||||
|
||||
return $descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <name> has a value
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasName(){
|
||||
return $this->_has(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear <name> value
|
||||
*
|
||||
* @return \helloworld\HelloRequest
|
||||
*/
|
||||
public function clearName(){
|
||||
return $this->_clear(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get <name> value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(){
|
||||
return $this->_get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set <name> value
|
||||
*
|
||||
* @param string $value
|
||||
* @return \helloworld\HelloRequest
|
||||
*/
|
||||
public function setName( $value){
|
||||
return $this->_set(1, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace helloworld {
|
||||
|
||||
class HelloReply extends \DrSlump\Protobuf\Message {
|
||||
|
||||
/** @var string */
|
||||
public $message = null;
|
||||
|
||||
|
||||
/** @var \Closure[] */
|
||||
protected static $__extensions = array();
|
||||
|
||||
public static function descriptor()
|
||||
{
|
||||
$descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
|
||||
|
||||
// OPTIONAL STRING message = 1
|
||||
$f = new \DrSlump\Protobuf\Field();
|
||||
$f->number = 1;
|
||||
$f->name = "message";
|
||||
$f->type = \DrSlump\Protobuf::TYPE_STRING;
|
||||
$f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
|
||||
$descriptor->addField($f);
|
||||
|
||||
foreach (self::$__extensions as $cb) {
|
||||
$descriptor->addField($cb(), true);
|
||||
}
|
||||
|
||||
return $descriptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if <message> has a value
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function hasMessage(){
|
||||
return $this->_has(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear <message> value
|
||||
*
|
||||
* @return \helloworld\HelloReply
|
||||
*/
|
||||
public function clearMessage(){
|
||||
return $this->_clear(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get <message> value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getMessage(){
|
||||
return $this->_get(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set <message> value
|
||||
*
|
||||
* @param string $value
|
||||
* @return \helloworld\HelloReply
|
||||
*/
|
||||
public function setMessage( $value){
|
||||
return $this->_set(1, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace helloworld {
|
||||
|
||||
class GreeterClient{
|
||||
|
||||
private $rpc_impl;
|
||||
|
||||
public function __construct($rpc_impl) {
|
||||
$this->rpc_impl = $rpc_impl;
|
||||
}
|
||||
/**
|
||||
* @param helloworld\HelloRequest $input
|
||||
*/
|
||||
public function SayHello(\helloworld\HelloRequest $argument, $metadata = array()) {
|
||||
return $this->rpc_impl->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// Copyright 2015, Google Inc.
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
option java_package = "ex.grpc";
|
||||
|
||||
package helloworld;
|
||||
|
||||
// The greeting service definition.
|
||||
service Greeter {
|
||||
// Sends a greeting
|
||||
rpc SayHello (HelloRequest) returns (HelloReply) {}
|
||||
}
|
||||
|
||||
// The request message containing the user's name.
|
||||
message HelloRequest {
|
||||
optional string name = 1;
|
||||
}
|
||||
|
||||
// The response message containing the greetings
|
||||
message HelloReply {
|
||||
optional string message = 1;
|
||||
}
|
||||
|
|
@ -3,4 +3,4 @@
|
|||
|
||||
source 'https://rubygems.org/'
|
||||
|
||||
gemspec
|
||||
gem 'grpc', :git => 'https://github.com/grpc/grpc.git', :submodules => true, glob: 'src/ruby/*.gemspec'
|
||||
|
|
|
|||
|
|
@ -3,66 +3,59 @@ gRPC in 3 minutes (Ruby)
|
|||
|
||||
BACKGROUND
|
||||
-------------
|
||||
For this sample, we've already generated the server and client stubs from [helloworld.proto](https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto).
|
||||
For this sample, we've already generated the server and client stubs from [helloworld.proto][]
|
||||
|
||||
PREREQUISITES
|
||||
-------------
|
||||
|
||||
- Ruby 2.x
|
||||
|
||||
This requires Ruby 2.x, as the gRPC API surface uses keyword args.
|
||||
If you don't have that installed locally, you can use [RVM](https://www.rvm.io/) to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system.
|
||||
If you don't have that installed locally, you can use [RVM][] to use Ruby 2.x for testing without upgrading the version of Ruby on your whole system.
|
||||
RVM is also useful if you don't have the necessary privileges to update your system's Ruby.
|
||||
```sh
|
||||
$ # RVM installation as specified at https://rvm.io/rvm/install
|
||||
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
||||
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
|
||||
$
|
||||
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
|
||||
$ # and that the rvm command is installed
|
||||
```
|
||||
|
||||
```sh
|
||||
$ # RVM installation as specified at https://rvm.io/rvm/install
|
||||
$ gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
|
||||
$ \curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2
|
||||
$
|
||||
$ # follow the instructions to ensure that your're using the latest stable version of Ruby
|
||||
$ # and that the rvm command is installed
|
||||
```
|
||||
- *N.B* Make sure your run `source $HOME/.rvm/scripts/rvm` as instructed to complete the set-up of RVM.
|
||||
|
||||
- Homebrew/Linuxbrew
|
||||
|
||||
The gRPC core will be installed using [Linuxbrew][Linuxbrew] for Linux and [Homebrew][Homebrew] on Macs.
|
||||
Please ensure these are installed before proceeding.
|
||||
|
||||
INSTALL
|
||||
-------
|
||||
|
||||
- Clone this repository
|
||||
- Install gRPC Ruby using the brew-based installer
|
||||
```sh
|
||||
$ curl -fsSL https://raw.githubusercontent.com/tbetbetbe/homebrew-grpc/master/scripts/install | bash -s ruby
|
||||
```
|
||||
|
||||
- Use bundler to install the example package's dependencies
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ gem install bundler # if you don't already have bundler available
|
||||
$ bundle install
|
||||
```
|
||||
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ gem install bundler # if you don't already have bundler available
|
||||
$ bundle install
|
||||
```
|
||||
|
||||
Try it!
|
||||
-------
|
||||
|
||||
- Run the server
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ bundle exec ./greeter_server.rb &
|
||||
```
|
||||
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ bundle exec ./greeter_server.rb &
|
||||
```
|
||||
|
||||
- Run the client
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ bundle exec ./greeter_client.rb
|
||||
```
|
||||
|
||||
```sh
|
||||
$ # from this directory
|
||||
$ bundle exec ./greeter_client.rb
|
||||
```
|
||||
|
||||
Tutorial
|
||||
--------
|
||||
|
||||
You can find a more detailed tutorial in [gRPC Basics: Ruby](https://github.com/grpc/grpc-common/blob/master/ruby/route_guide/README.md)
|
||||
|
||||
[Homebrew]: https://github.com/Homebrew/homebrew
|
||||
[Linuxbrew]: https://github.com/Homebrew/linuxbrew
|
||||
[helloworld.proto]:https://github.com/grpc/grpc-common/blob/master/protos/helloworld.proto
|
||||
[RVM]:https://www.rvm.io/
|
||||
|
|
|
|||
Loading…
Reference in New Issue