Skip to content
Permalink
Browse files

Convert hosted app to use gRPC for weather forecast

  • Loading branch information
SteveSandersonMS committed Jan 10, 2020
1 parent 73278a9 commit 72544c54085a35cd89aae20030d7f91d75317a2f
@@ -6,10 +6,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Grpc.Net.Client.Web" Version="2.27.0-dev202001100801" />
<PackageReference Include="Microsoft.AspNetCore.Blazor" Version="3.1.0-preview4.19579.2" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="3.1.0-preview4.19579.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.1.0-preview4.19579.2" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="3.1.0-preview4.19579.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.Mono" Version="3.2.0-preview1.20052.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Shared\BlazorGrpcHosted.Shared.csproj" />
@@ -1,6 +1,6 @@
@page "/fetchdata"
@using BlazorGrpcHosted.Shared
@inject HttpClient Http
@inject WeatherForecasts.WeatherForecastsClient WeatherForecastsClient

<h1>Weather forecast</h1>

@@ -36,11 +36,11 @@ else
}

@code {
private WeatherForecast[] forecasts;
private IList<WeatherForecast> forecasts;

protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetJsonAsync<WeatherForecast[]>("WeatherForecast");
forecasts = (await WeatherForecastsClient.GetWeatherAsync(new Empty())).Forecasts;
}

}
@@ -1,12 +1,27 @@
using BlazorGrpcHosted.Shared;
using Grpc.Net.Client;
using Grpc.Net.Client.Web;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Builder;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;

namespace BlazorGrpcHosted.Client
{
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(services =>
{
// Create a gRPC-Web channel pointing to the backend server
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
var baseUri = services.GetRequiredService<NavigationManager>().BaseUri;
var channel = GrpcChannel.ForAddress(baseUri, new GrpcChannelOptions { HttpClient = httpClient });

// Now we can instantiate gRPC clients for this channel
return new WeatherForecasts.WeatherForecastsClient(channel);
});
}

public void Configure(IComponentsApplicationBuilder app)
@@ -5,3 +5,4 @@
@using Microsoft.JSInterop
@using BlazorGrpcHosted.Client
@using BlazorGrpcHosted.Client.Shared
@using Google.Protobuf.WellKnownTypes
@@ -6,6 +6,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.27.0-dev202001100801" />
<PackageReference Include="Grpc.AspNetCore.Web" Version="2.27.0-dev202001100801" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.Server" Version="3.1.0-preview4.19579.2" />
</ItemGroup>

This file was deleted.

@@ -0,0 +1,32 @@
using BlazorGrpcHosted.Shared;
using System;
using System.Linq;
using System.Threading.Tasks;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;

namespace BlazorGrpcHosted.Server.Services
{
public class WeatherForecastsService : WeatherForecasts.WeatherForecastsBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};

public override Task<WeatherReply> GetWeather(Empty request, ServerCallContext context)
{
var reply = new WeatherReply();

var rng = new Random();
reply.Forecasts.Add(Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
}));

return Task.FromResult(reply);
}
}
}
@@ -1,3 +1,4 @@
using BlazorGrpcHosted.Server.Services;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.ResponseCompression;
@@ -13,7 +14,7 @@ public class Startup
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddGrpc();
services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
@@ -36,10 +37,11 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
app.UseClientSideBlazorFiles<Client.Startup>();

app.UseRouting();
app.UseGrpcWeb();

app.UseEndpoints(endpoints =>
{
endpoints.MapDefaultControllerRoute();
endpoints.MapGrpcService<WeatherForecastsService>().EnableGrpcWeb();
endpoints.MapFallbackToClientSideBlazor<Client.Startup>("index.html");
});
}
@@ -5,4 +5,17 @@
<LangVersion>7.3</LangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.11.2" />
<PackageReference Include="Grpc.Net.Client" Version="2.27.0-dev202001100801" />
<PackageReference Include="Grpc.Tools" Version="2.27.0-dev202001081219">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

<ItemGroup>
<Protobuf Include="weather.proto" />
</ItemGroup>

</Project>
@@ -1,16 +1,18 @@
using System;
using System.Collections.Generic;
using System.Text;
using Google.Protobuf.WellKnownTypes;

namespace BlazorGrpcHosted.Shared
{
public class WeatherForecast
public partial class WeatherForecast
{
public DateTime Date { get; set; }
// Properties for the underlying data are generated from the .proto file
// This partial class just adds some extra convenience properties

public int TemperatureC { get; set; }

public string Summary { get; set; }
public DateTime Date
{
get => DateTimeStamp.ToDateTime();
set { DateTimeStamp = Timestamp.FromDateTime(value.ToUniversalTime()); }
}

public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
@@ -0,0 +1,22 @@
syntax = "proto3";

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

option csharp_namespace = "BlazorGrpcHosted.Shared";

package WeatherForecast;

service WeatherForecasts {
rpc GetWeather (google.protobuf.Empty) returns (WeatherReply);
}

message WeatherReply {
repeated WeatherForecast forecasts = 1;
}

message WeatherForecast {
google.protobuf.Timestamp dateTimeStamp = 1;
int32 temperatureC = 2;
string summary = 3;
}

0 comments on commit 72544c5

Please sign in to comment.
You can’t perform that action at this time.