mirror of https://github.com/grpc/grpc.git
commit
8f0e8275c5
7 changed files with 321 additions and 0 deletions
@ -0,0 +1,34 @@ |
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||
# Visual Studio 15 |
||||
VisualStudioVersion = 15.0.26228.4 |
||||
MinimumVisualStudioVersion = 10.0.40219.1 |
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Greeter", "Greeter\Greeter.csproj", "{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}" |
||||
EndProject |
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreeterClient", "GreeterClient\GreeterClient.csproj", "{B754FB02-D501-4308-8B89-33AB7119C80D}" |
||||
EndProject |
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GreeterServer", "GreeterServer\GreeterServer.csproj", "{DDBFF994-E076-43AD-B18D-049DFC1B670C}" |
||||
EndProject |
||||
Global |
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||
Debug|Any CPU = Debug|Any CPU |
||||
Release|Any CPU = Release|Any CPU |
||||
EndGlobalSection |
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{13B6DFC8-F5F6-4CC2-99DF-57A7CF042033}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{B754FB02-D501-4308-8B89-33AB7119C80D}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{B754FB02-D501-4308-8B89-33AB7119C80D}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU |
||||
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Debug|Any CPU.Build.0 = Debug|Any CPU |
||||
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.ActiveCfg = Release|Any CPU |
||||
{DDBFF994-E076-43AD-B18D-049DFC1B670C}.Release|Any CPU.Build.0 = Release|Any CPU |
||||
EndGlobalSection |
||||
GlobalSection(SolutionProperties) = preSolution |
||||
HideSolutionNode = FALSE |
||||
EndGlobalSection |
||||
EndGlobal |
@ -0,0 +1,20 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>netstandard2.0</TargetFramework> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<PackageReference Include="Google.Protobuf" Version="3.12.2" /> |
||||
<PackageReference Include="Grpc.Core" Version="2.29.0" /> |
||||
<PackageReference Include="Grpc.HealthCheck" Version="2.29.0" /> |
||||
<PackageReference Include="Grpc.Reflection" Version="2.29.0"/> |
||||
<PackageReference Include="CommandLineParser" Version="2.8.0" /> |
||||
<PackageReference Include="Grpc.Tools" Version="2.29.0" PrivateAssets="All" /> |
||||
</ItemGroup> |
||||
|
||||
<ItemGroup> |
||||
<Protobuf Include="../../../protos/helloworld.proto" Link="helloworld.proto" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,12 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>netcoreapp2.1</TargetFramework> |
||||
<OutputType>Exe</OutputType> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<ProjectReference Include="..\Greeter\Greeter.csproj" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,51 @@ |
||||
// 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. |
||||
|
||||
using System; |
||||
using Grpc.Core; |
||||
using Helloworld; |
||||
using CommandLine; |
||||
|
||||
namespace GreeterClient |
||||
{ |
||||
class Program |
||||
{ |
||||
private class Options |
||||
{ |
||||
[Option("server", Default = "localhost:50051", HelpText = "The address of the server")] |
||||
public string Server { get; set; } |
||||
} |
||||
|
||||
public static void Main(string[] args) |
||||
{ |
||||
Parser.Default.ParseArguments<Options>(args) |
||||
.WithParsed<Options>(options => RunClient(options)); |
||||
} |
||||
|
||||
private static void RunClient(Options options) |
||||
{ |
||||
Channel channel = new Channel(options.Server, ChannelCredentials.Insecure); |
||||
|
||||
var client = new Greeter.GreeterClient(channel); |
||||
String user = "you"; |
||||
|
||||
var reply = client.SayHello(new HelloRequest { Name = user }); |
||||
Console.WriteLine("Greeter client received: " + reply.Message); |
||||
|
||||
channel.ShutdownAsync().Wait(); |
||||
Console.WriteLine("Press any key to exit..."); |
||||
Console.ReadKey(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,12 @@ |
||||
<Project Sdk="Microsoft.NET.Sdk"> |
||||
|
||||
<PropertyGroup> |
||||
<TargetFramework>netcoreapp2.1</TargetFramework> |
||||
<OutputType>Exe</OutputType> |
||||
</PropertyGroup> |
||||
|
||||
<ItemGroup> |
||||
<ProjectReference Include="..\Greeter\Greeter.csproj" /> |
||||
</ItemGroup> |
||||
|
||||
</Project> |
@ -0,0 +1,93 @@ |
||||
// Copyright 2020 The 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. |
||||
|
||||
using System; |
||||
using System.Net; |
||||
using System.Threading.Tasks; |
||||
using Grpc.Core; |
||||
using Grpc.HealthCheck; |
||||
using Helloworld; |
||||
using Grpc.Health; |
||||
using Grpc.Health.V1; |
||||
using Grpc.Reflection; |
||||
using Grpc.Reflection.V1Alpha; |
||||
using CommandLine; |
||||
|
||||
namespace GreeterServer |
||||
{ |
||||
class GreeterImpl : Greeter.GreeterBase |
||||
{ |
||||
private string hostname; |
||||
|
||||
public GreeterImpl(string hostname) |
||||
{ |
||||
this.hostname = hostname; |
||||
} |
||||
|
||||
// Server side handler of the SayHello RPC |
||||
public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context) |
||||
{ |
||||
return Task.FromResult(new HelloReply { Message = $"Hello {request.Name} from {hostname}!"}); |
||||
} |
||||
} |
||||
|
||||
class Program |
||||
{ |
||||
class Options |
||||
{ |
||||
[Option("port", Default = 50051, HelpText = "The port to listen on.")] |
||||
public int Port { get; set; } |
||||
|
||||
[Option("hostname", Required = false, HelpText = "The name clients will see in responses. If not specified, machine's hostname will obtain automatically.")] |
||||
public string Hostname { get; set; } |
||||
} |
||||
|
||||
public static void Main(string[] args) |
||||
{ |
||||
Parser.Default.ParseArguments<Options>(args) |
||||
.WithParsed<Options>(options => RunServer(options)); |
||||
} |
||||
|
||||
private static void RunServer(Options options) |
||||
{ |
||||
var hostName = options.Hostname ?? Dns.GetHostName(); |
||||
|
||||
var serviceDescriptors = new [] {Greeter.Descriptor, Health.Descriptor, ServerReflection.Descriptor}; |
||||
var greeterImpl = new GreeterImpl(hostName); |
||||
var healthServiceImpl = new HealthServiceImpl(); |
||||
var reflectionImpl = new ReflectionServiceImpl(serviceDescriptors); |
||||
|
||||
Server server = new Server |
||||
{ |
||||
Services = { Greeter.BindService(greeterImpl), Health.BindService(healthServiceImpl), ServerReflection.BindService(reflectionImpl) }, |
||||
Ports = { new ServerPort("[::]", options.Port, ServerCredentials.Insecure) } |
||||
}; |
||||
server.Start(); |
||||
|
||||
// Mark all services as healthy. |
||||
foreach (var serviceDescriptor in serviceDescriptors) |
||||
{ |
||||
healthServiceImpl.SetStatus(serviceDescriptor.FullName, HealthCheckResponse.Types.ServingStatus.Serving); |
||||
} |
||||
// Mark overall server status as healthy. |
||||
healthServiceImpl.SetStatus("", HealthCheckResponse.Types.ServingStatus.Serving); |
||||
|
||||
Console.WriteLine("Greeter server listening on port " + options.Port); |
||||
Console.WriteLine("Press any key to stop the server..."); |
||||
Console.ReadKey(); |
||||
|
||||
server.ShutdownAsync().Wait(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,99 @@ |
||||
gRPC Hostname example (C#) |
||||
======================== |
||||
|
||||
BACKGROUND |
||||
------------- |
||||
This is a version of the helloworld example with a server whose response includes its hostname. It also supports health and reflection services. This makes it a good server to test infrastructure, such as XDS load balancing. |
||||
|
||||
PREREQUISITES |
||||
------------- |
||||
|
||||
- The [.NET Core SDK 2.1+](https://www.microsoft.com/net/core) |
||||
|
||||
You can also build the solution `Greeter.sln` using Visual Studio 2019, |
||||
but it's not a requirement. |
||||
|
||||
RUN THE EXAMPLE |
||||
------------- |
||||
|
||||
First, build and run the server, then verify the server is running and |
||||
check the server is behaving as expected (more on that below). |
||||
|
||||
``` |
||||
cd GreeterServer |
||||
dotnet run |
||||
``` |
||||
|
||||
After configuring your xDS server to track the gRPC server we just started, |
||||
create a bootstrap file as desribed in [gRFC A27](https://github.com/grpc/proposal/blob/master/A27-xds-global-load-balancing.md): |
||||
|
||||
``` |
||||
{ |
||||
xds_servers": [ |
||||
{ |
||||
"server_uri": <string containing URI of xds server>, |
||||
"channel_creds": [ |
||||
{ |
||||
"type": <string containing channel cred type>, |
||||
"config": <JSON object containing config for the type> |
||||
} |
||||
] |
||||
} |
||||
], |
||||
"node": <JSON form of Node proto> |
||||
} |
||||
``` |
||||
|
||||
Then point the `GRPC_XDS_BOOTSTRAP` environment variable at the bootstrap file: |
||||
|
||||
``` |
||||
export GRPC_XDS_BOOTSTRAP=/etc/xds-bootstrap.json |
||||
``` |
||||
|
||||
Finally, run your client: |
||||
|
||||
``` |
||||
cd GreeterClient |
||||
dotnet run --server xds-experimental:///my-backend |
||||
``` |
||||
|
||||
VERIFYING THE SERVER |
||||
------------- |
||||
|
||||
`grpcurl` can be used to test your server. If you don't have it, |
||||
install [`grpcurl`](https://github.com/fullstorydev/grpcurl/releases). This will allow |
||||
you to manually test the service. |
||||
|
||||
Exercise your server's application-layer service: |
||||
|
||||
```sh |
||||
> grpcurl --plaintext -d '{"name": "you"}' localhost:50051 |
||||
{ |
||||
"message": "Hello you from jtatt.muc.corp.google.com!" |
||||
} |
||||
``` |
||||
|
||||
Make sure that all of your server's services are available via reflection: |
||||
|
||||
```sh |
||||
> grpcurl --plaintext localhost:50051 list |
||||
grpc.health.v1.Health |
||||
grpc.reflection.v1alpha.ServerReflection |
||||
helloworld.Greeter |
||||
``` |
||||
|
||||
Make sure that your services are reporting healthy: |
||||
|
||||
```sh |
||||
> grpcurl --plaintext -d '{"service": "helloworld.Greeter"}' localhost:50051 |
||||
grpc.health.v1.Health/Check |
||||
{ |
||||
"status": "SERVING" |
||||
} |
||||
|
||||
> grpcurl --plaintext -d '{"service": ""}' localhost:50051 |
||||
grpc.health.v1.Health/Check |
||||
{ |
||||
"status": "SERVING" |
||||
} |
||||
``` |
Loading…
Reference in new issue