Skip to content

Commit

Permalink
gRPC APIs on .NET demo
Browse files Browse the repository at this point in the history
  • Loading branch information
binodmahto authored Dec 1, 2021
1 parent 1ee0503 commit d8c32dc
Show file tree
Hide file tree
Showing 19 changed files with 630 additions and 0 deletions.
22 changes: 22 additions & 0 deletions grpcAPIsDemo/GrpcClientDemo/GrpcClientDemo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.19.1" />
<PackageReference Include="Grpc.Net.Client" Version="2.40.0" />
<PackageReference Include="Grpc.Tools" Version="2.42.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Client" />
<Protobuf Include="Protos\weatherForecast.proto" GrpcServices="Client" />
</ItemGroup>
</Project>
25 changes: 25 additions & 0 deletions grpcAPIsDemo/GrpcClientDemo/GrpcClientDemo.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcClientDemo", "GrpcClientDemo.csproj", "{668BCD8E-2FB5-4902-8FEE-9C1198FB70C5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{668BCD8E-2FB5-4902-8FEE-9C1198FB70C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{668BCD8E-2FB5-4902-8FEE-9C1198FB70C5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{668BCD8E-2FB5-4902-8FEE-9C1198FB70C5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{668BCD8E-2FB5-4902-8FEE-9C1198FB70C5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C0F3AB54-7840-4E05-9C2A-AE29C26B034F}
EndGlobalSection
EndGlobal
138 changes: 138 additions & 0 deletions grpcAPIsDemo/GrpcClientDemo/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@

using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Grpc.Net.Client;
using GrpcServiceDemo;

// The port number must match the port of the gRPC server.
using var channel = GrpcChannel.ForAddress("https://localhost:7001");
//var client = new Greeter.GreeterClient(channel);
//var reply = await client.SayHelloAsync(
// new HelloRequest { Name = "GrpcClientDemo" });
//Console.WriteLine("Greeting: " + reply.Message);
//Console.WriteLine("Press any key to exit...");

var weatherClient = new WeatherForcast.WeatherForcastClient(channel);

var request = new Google.Protobuf.WellKnownTypes.Empty();
var weatherInfo = weatherClient.GetWeatherForecast(request);
Console.WriteLine("*****Weather forecast for 5 days*****");
Console.WriteLine(weatherInfo.Result);
Console.WriteLine();

weatherInfo = weatherClient.GetWeatherForecastForDate(Timestamp.FromDateTime(DateTime.UtcNow));
Console.WriteLine("*****Weather forecast for today*****");
Console.WriteLine(weatherInfo.Result);
Console.WriteLine();

request = new Google.Protobuf.WellKnownTypes.Empty();
weatherInfo = await weatherClient.GetWeatherForecastAsync(request);
Console.WriteLine("*****Weather forecast for 5 days*****");
Console.WriteLine(weatherInfo.Result);
Console.WriteLine();

weatherInfo = await weatherClient.GetWeatherForecastForDateAsync(Timestamp.FromDateTime(DateTime.UtcNow));
Console.WriteLine("*****Weather forecast for today*****");
Console.WriteLine(weatherInfo.Result);
Console.WriteLine();

Console.WriteLine("*******Server Streaming weather forecast*******");
try
{
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(10));
using var streamingCall = weatherClient.GetWeatherForecastStream(new Empty(), cancellationToken: cancellationToken.Token);

await foreach (var weatherData in streamingCall.ResponseStream.ReadAllAsync(cancellationToken: cancellationToken.Token))
{
Console.WriteLine(weatherData);
}
Console.WriteLine("Stream completed.");
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
{
Console.WriteLine("Stream cancelled.");
}
Console.WriteLine();

Console.WriteLine("*******Client Streaming weather forecast*******");
try
{
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(10));
using AsyncClientStreamingCall<StreamMessage, WeatherForecastReply> clientStreamingCall = weatherClient.GetWeatherForecastClientStream(cancellationToken: cancellationToken.Token);
var i = 0;

while (true)
{
if (i >= 10)
{
await clientStreamingCall.RequestStream.CompleteAsync();
Console.WriteLine("Client Streaming completed.");
break;
}
else
{
//write to stream
await clientStreamingCall.RequestStream.WriteAsync(new StreamMessage { Index = i });
i++;
}
}
var response = await clientStreamingCall;
Console.WriteLine(response.Result);
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
{
Console.WriteLine("Stream cancelled.");
}
Console.WriteLine();

Console.WriteLine("*******Server & Client Duplex Streaming weather forecast*******");
try
{
var cancellationToken = new CancellationTokenSource(TimeSpan.FromSeconds(10));
using AsyncDuplexStreamingCall<StreamMessage, WeatherForecast> duplexStreamingCall = weatherClient.GetWeatherForecastDuplexStream(cancellationToken: cancellationToken.Token);
var i = 0;
Task task = Task.WhenAll(new[]
{
Task.Run(async () =>{
while (true)
{
if (i >= 10)
{
await duplexStreamingCall.RequestStream.CompleteAsync();
Console.WriteLine("Client Streaming completed.");
break;
}
else
{
//write to stream
await duplexStreamingCall.RequestStream.WriteAsync(new StreamMessage { Index = i });
i++;
}
}
}),
Task.Run(async () =>{
//read from stream
while (!cancellationToken.IsCancellationRequested && await duplexStreamingCall.ResponseStream.MoveNext())
{
Console.WriteLine(duplexStreamingCall.ResponseStream.Current);
}
})
});
try
{
task.Wait(cancellationToken.Token);
}
catch (OperationCanceledException e)
{
await duplexStreamingCall.RequestStream.CompleteAsync();
Thread.Sleep(6000);
}
}
catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
{
Console.WriteLine("Stream cancelled.");
}
Console.WriteLine();

Console.ReadKey();

21 changes: 21 additions & 0 deletions grpcAPIsDemo/GrpcClientDemo/Protos/greet.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
syntax = "proto3";

option csharp_namespace = "GrpcClientDemo";

package greet;

// The greeting service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply);
}

// The request message containing the user's name.
message HelloRequest {
string name = 1;
}

// The response message containing the greetings.
message HelloReply {
string message = 1;
}
45 changes: 45 additions & 0 deletions grpcAPIsDemo/GrpcClientDemo/Protos/weatherForecast.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
syntax = "proto3";

import "google/protobuf/timestamp.proto";
import "google/protobuf/empty.proto";

option csharp_namespace = "GrpcServiceDemo";

package weatherForcast;

// The weather forecast service definition.
service WeatherForcast {
// Get weather forecast: Unary RPCs
rpc GetWeatherForecast (google.protobuf.Empty) returns (WeatherForecastReply);

// Get weather forecast: Unary RPCs
rpc GetWeatherForecastForDate (google.protobuf.Timestamp) returns (WeatherForecastReply);

// Get weather forecast: Server Streaming RPCs
rpc GetWeatherForecastStream (google.protobuf.Empty) returns (stream WeatherForecast);

// Get weather forecast: Client Streaming RPCs
rpc GetWeatherForecastClientStream (stream StreamMessage) returns (WeatherForecastReply);

// Get weather forecast: Bidirectional streaming RPCs
rpc GetWeatherForecastDuplexStream (stream StreamMessage) returns (stream WeatherForecast);
}

// The response message containing the weather information.
message WeatherForecastReply {
repeated WeatherForecast Result = 1;
}

message WeatherForecast {
google.protobuf.Timestamp Date = 1;

int32 TemperatureC = 2;

int32 TemperatureF = 3;

string Summary = 4;
}

message StreamMessage{
int32 index = 1;
}
22 changes: 22 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["GrpcServiceDemo.csproj", "."]
RUN dotnet restore "./GrpcServiceDemo.csproj"
COPY . .
WORKDIR "/src/."
RUN dotnet build "GrpcServiceDemo.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "GrpcServiceDemo.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "GrpcServiceDemo.dll"]
22 changes: 22 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/GrpcServiceDemo.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>ba4848bf-81dd-407c-b1a3-fcf960b4841d</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<DockerfileContext>.</DockerfileContext>
</PropertyGroup>

<ItemGroup>
<Protobuf Include="Protos\greet.proto" GrpcServices="Server" />
<Protobuf Include="Protos\weatherForecast.proto" GrpcServices="Server" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.40.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.14.0" />
</ItemGroup>

</Project>
9 changes: 9 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/GrpcServiceDemo.csproj.user
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>GrpcServiceDemo</ActiveDebugProfile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>
25 changes: 25 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/GrpcServiceDemo.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcServiceDemo", "GrpcServiceDemo.csproj", "{3BB1A4FD-AE91-408D-9B04-71363AD18768}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3BB1A4FD-AE91-408D-9B04-71363AD18768}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3BB1A4FD-AE91-408D-9B04-71363AD18768}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3BB1A4FD-AE91-408D-9B04-71363AD18768}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3BB1A4FD-AE91-408D-9B04-71363AD18768}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {67CAB8CF-D393-4EBD-A444-91083BC59727}
EndGlobalSection
EndGlobal
19 changes: 19 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using GrpcServiceDemo.Services;

var builder = WebApplication.CreateBuilder(args);

// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682

// Add services to the container.
builder.Services.AddGrpc();
builder.Services.AddTransient<IWeatherForecastService, WeatherForecastService>();
var app = builder.Build();


// Configure the HTTP request pipeline.
app.MapGrpcService<GreeterService>();
app.MapGrpcService<WeatherForecastGrpcService>();
app.MapGet("/", () => "Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");

app.Run();
18 changes: 18 additions & 0 deletions grpcAPIsDemo/GrpcServiceDemo/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"profiles": {
"GrpcServiceDemo": {
"commandName": "Project",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:5001;https://localhost:7001",
"dotnetRunMessages": true
},
"Docker": {
"commandName": "Docker",
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}",
"publishAllPorts": true,
"useSSL": true
}
}
}
Loading

0 comments on commit d8c32dc

Please sign in to comment.