grpc与web服务共存_在blazor webassembly中用grpc web替换休息服务的10个步骤

grpc与web服务共存

In modern web applications, the common way data is exchanged between client and server is through REST (representational state transfer) services. JSON is the standard file format for this two-way communication.

在现代Web应用程序中,在客户端和服务器之间交换数据的通用方式是通过REST(表示状态传输)服务JSON是这种双向通信的标准文件格式。

In REST, the client makes a request to a specific endpoint, and the server responds to it.

在REST中,客户端向特定端点发出请求,然后服务器对此做出响应。

This architectural style works fine and has been the standard for several years. All web frameworks for creating SPA (single-page applications) are based on it. At first glance, even Blazor WebAssembly seems to use REST just like other frameworks.

这种建筑风格效果很好,并且已经成为多年的标准。 用于创建SPA(单页应用程序)的所有Web框架均基于该框架。 乍一看,甚至Blazor WebAssembly似乎也像其他框架一样使用REST。

Despite the wide use of this standard, there are some critical issues to consider:

尽管已广泛使用此标准,但仍需要考虑一些关键问题:

  • If it is true that JSON is less verbose than XML, then it is also true that it is not optimized for bandwidth. Sometimes, JSON structure gets much too complicated.

    如果确实JSON比XML冗长,那么也没有针对带宽进行优化。 有时,JSON结构变得过于复杂。
  • REST APIs are stateless. This can have some negative consequences; for example, all requests should contain all the necessary information in order to perform the desired operations.

    REST API是无状态的。 这可能会带来一些负面影响; 例如,所有请求都应包含所有必要的信息,以便执行所需的操作。
  • REST is not a protocol, but an architectural style. This involves increasing the responsibilities of developers. Most implementations of REST use only a subset of its principles but work, more or less. Often there is a confusion between REST services and RESTful services (those that implement REST services).

    REST不是协议,而是一种体系结构样式。 这涉及增加开发人员的责任。 REST的大多数实现仅使用其原理的一个子集,但是或多或少地起作用。 REST服务和RESTful服务(那些实现REST服务的服务)之间常常会混淆。

To be clear, REST architecture remains a great way to exchange data between clients and servers, but perhaps today we can afford to look beyond to find alternative solutions.

需要明确的是,REST体系结构仍然是在客户端和服务器之间交换数据的好方法,但是也许今天我们可以负担得起寻找替代解决方案的费用。

什么是gRPC和gRPC-Web? (What are gRPC and gRPC-Web?)

gRPC is a remote procedure call system created at Google in 2015. It is open source and can be defined as a replacement for Windows Communication Foundation (WCF). However, thanks to the latest update, it can also substitute REST API.

gRPC是Google在2015年创建的一个远程过程调用系统。它是开源的,可以定义为Windows Communication Foundation(WCF)的替代品。 但是,由于最新的更新,它也可以替代REST API。

gRPC uses Protobuf (Protocol Buffers) as the format for the payload and supports all kinds of streaming:

gRPC使用Protobuf (协议缓冲区)作为有效负载的格式,并支持所有类型的流传输:

  • Server-side streaming

    服务器端流
  • Client-side streaming

    客户端流
  • Bidirectional streaming

    双向流

From a performance point of view, Protobuf is an efficient binary message format. Protobuf serialization results in small message payloads, which is important in limited-bandwidth scenarios like mobile and web apps.

从性能的角度来看,Protobuf是一种有效的二进制消息格式。 Protobuf序列化会产生较小的消息负载,这在移动和Web应用程序等有限带宽的情况下非常重要。

gRPC defines the contract of services and messages by the .proto file shared between the server and client. It allows you to automatically generate client libraries. gRPC is consistent across platforms and implementations.

gRPC通过服务器和客户端之间共享的.proto文件定义服务和消息的约定 。 它允许您自动生成客户端库。 gRPC在平台和实现之间是一致的。

The following table shows a comparison of features between gRPC and REST APIs with JSON format.

下表显示了gRPC和JSON格式的REST API之间的功能比较。

Features comparison between gRPC and REST APIs with JSON format

All of this sounds great, doesn’t it? Unfortunately, there’s bad news!

所有这些听起来很棒,不是吗? 不幸的是,有个坏消息!

gRPC can’t be used from within web browsers because it requires HTTP/2 binary protocol. Don’t worry, the solution to this problem is called gRPC-Web, which makes gRPC usable in the browser. There’s also an implementation of gRPC-Web for .NET that has been officially released.

不能在Web浏览器中使用gRPC,因为它需要HTTP / 2二进制协议。 不用担心,该问题的解决方案称为gRPC-Web ,它使gRPC在浏览器中可用。 NETgRPC-Web实现也已正式发布。

To be fair, gRPC-Web provides limited gRPC support. For example, client and bi-directional streaming aren’t supported, and there is limited support for server streaming too.

公平地说, gRPC-Web提供有限的gRPC支持。 例如,不支持客户端和双向流,并且对服务器流的支持也很有限。

After this preamble, it’s time to go from theory to practice!

在这篇序言之后,是时候从理论转向实践了!

In this post I’ll show you how to consume a gRPC-Web service from within a Blazor WebAssembly app to build weather forecasting application. At the time of writing, there’s no native project template for this yet, so adding gRPC support to a Blazor WebAssembly app is a somewhat significant task. But again, don’t worry. No part of this is complicated. It’s only 10 small steps!

在本文中,我将向您展示如何从Blazor WebAssembly应用程序中使用gRPC-Web服务来构建天气预报应用程序 。 在撰写本文时,尚无本机项目模板,因此向Blazor WebAssembly应用程序添加gRPC支持是一项相当重要的任务。 但同样,不用担心。 这没有什么复杂的。 仅十步之遥!

Step 1

第1步

Create a Blazor WebAssembly ASP.NET Core-hosted solution, and name it BlazorGrpc. Refer to the following screenshot.

创建一个Blazor WebAssembly ASP.NET Core托管的解决方案,并将其命名为BlazorGrpc 。 请参考以下屏幕截图。

Create a Blazor WebAssembly ASP.NET Core-hosted solution, and name it as BlazorGrpc

Step 2

第2步

These are the changes that need to be made to the project files to add dependencies and more. BlazorGrpc.Shared.csproj

这些是需要对项目文件进行的更改,以添加依赖项等。 BlazorGrpc.Shared.csproj

<ItemGroup> 
<None Remove="weatherforecast.proto" />
</ItemGroup> <ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.13.0" /> <PackageReference Include="Grpc.Net.Client" Version="2.31.0" /> <PackageReference Include="Grpc.Tools" Version="2.31.0"> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup> <ItemGroup>
<Protobuf Include="weatherforecast.proto" />
</ItemGroup>

BlazorGrpc.Server.csproj

BlazorGrpc.Server.csproj

<PackageReference Include="Grpc.AspNetCore" Version="2.31.0" /> <PackageReference Include="Grpc.AspNetCore.Web" Version="2.31.0" />

BlazorGrpc.Client.csproj

BlazorGrpc.Client.csproj

<PackageReference Include="Grpc.Net.Client.Web" Version="2.31.0" />

Step 3

第三步

In the Shared project, create a weatherforecast.proto file like the code example below.

Shared项目中 ,创建一个weatherforecast.proto文件,如下面的代码示例所示。

syntax = "proto3"; import "google/protobuf/empty.proto"; 
import "google/protobuf/timestamp.proto"; option csharp_namespace = "BlazorGrpc.Shared"; package WeatherForecast; service WeatherForecastService {
rpc GetWeatherForecast (google.protobuf.Empty) returns (WeatherForecastResponse);
} message WeatherForecastResponse {
repeated WeatherForecast forecasts = 1;
} message WeatherForecast {
google.protobuf.Timestamp dateTimeStamp = 1;
int32 temperatureC = 2;
string summary = 3;
}

The .proto file defines the service and everything necessary to run it correctly.

.proto文件定义了服务以及正确运行该服务所需的一切。

If you want to learn more about the syntax of this file, refer to this documentation: https://developers.google.com/protocol-buffers/docs/proto3

如果您想了解有关此文件语法的更多信息,请参阅以下文档: https : //developers.google.com/protocol-buffers/docs/proto3

Step 4

第4步

Go to the file properties and select the Protobuf compiler as the Build Action. A new window will appear thanks to the NuGet package Grpc.Tools. Then, select the Client and Server option as the gRPC Stub Classes. Refer to the following screenshot.

转到文件属性,然后选择Protobuf编译器作为Build Action 。 由于使用了NuGet软件包Grpc.Tools,将出现一个新窗口。 然后,选择“ 客户端和服务器”选项作为gRPC Stub类 。 请参考以下屏幕截图。

select the Protobuf compiler as the Build Action and select the Client and Server option as the gRPC Stub Classes

Step 5

第5步

Modify the WeatherForecast partial class with the following code snippets. Keep in mind that the main properties of this class are generated from the .proto file; however, you can also add some extra useful properties to this partial class.

使用以下代码段修改WeatherForecast子类。 请记住,此类的主要属性是从.proto文件生成的; 但是,您也可以向此部分类添加一些额外的有用属性。

using System; 
using Google.Protobuf.WellKnownTypes;
namespace Blazorgrpc.Shared
{ public partial class WeatherForecast
{
public DateTime Date
{
get => DateTimeStamp.ToDateTime();
set { DateTimeStamp = Timestamp.FromDateTime(value.ToUniversalTime()); }
}
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}
}

Step 6

第6步

In the Server project, add gRPC services to the container. In the Startup.cs file, modify the ConfigureServices method by adding this code:

Server项目中 ,将gRPC服务添加到容器中。 在Startup.cs文件中,通过添加以下代码来修改ConfigureServices方法:

services.AddGrpc();

To optimize the performance, I recommend taking advantage of response compression by adding the following code too:

为了优化性能,我建议也通过添加以下代码来利用响应压缩:

services.AddResponseCompression(opts =>
{
opts.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/octet-stream" });
});

Step 7

步骤7

Now, it’s time to implement the logic of our application in a service class, add it to the container, and also use it to modify the controller generated by the template. The service class will be something like the code below.

现在,是时候在服务类中实现应用程序的逻辑,将其添加到容器中,并使用它来修改模板生成的控制器了。 服务类将类似于以下代码。

public class WeatherForecastService : BlazorGrpc.Shared.WeatherForecastService.WeatherForecastServiceBase { 
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
}; public override Task<WeatherForecastResponse> GetWeatherForecast(Empty request, ServerCallContext context)
{
var response = new WeatherForecastResponse(); response.Forecasts.AddRange(GetWeatherForecast()); return Task.FromResult<WeatherForecastResponse>(response);
} public IEnumerable<WeatherForecast> GetWeatherForecast()
{
var rng = new Random();
return Enumerable.Range(1, 365).Select(index => new WeatherForecast {
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
});
}
}

Note: The WeatherForecastService class is inherited from BlazorGrpc.Shared.WeatherForecastService.WeatherForecastServiceBase, which is generated automatically from the .proto file.

注意: WeatherForecastService类继承自BlazorGrpc.Shared.WeatherForecastService.WeatherForecastServiceBase,该类是从.proto文件自动生成的。

Step 8

步骤8

Go back to the Startup.cs file to configure the gRPC-Web middleware in the Configure method as shown in the following code, so that all the services will support gRPC-Web by default.

返回到Startup.cs文件,以Configure方法配置gRPC-Web中间件,如下面的代码所示,以便默认情况下所有服务都将支持gRPC-Web。

app.UseGrpcWeb(new GrpcWebOptions { DefaultEnabled = true });

Then, add the route with the following code:

然后,使用以下代码添加路由:

app.UseEndpoints(endpoints => 
{
endpoints.MapGrpcService<WeatherForecastService>();
}

Step 9

步骤9

Let’s move on to the client project. First, add the WeatherForecastService to the container, then create a gRPC-Web channel pointing to the back-end server and instantiate the gRPC clients for this channel.

让我们继续进行客户项目。 首先,将WeatherForecastService添加到容器中,然后创建一个指向后端服务器的gRPC-Web通道,并为该通道实例化gRPC客户端。

Refer to the following code to modify the Program.cs file, to which we need to add additional required namespaces.

请参考以下代码来修改Program.cs文件,我们需要在该文件中添加其他必需的名称空间。

builder.Services. AddSingleton(services => 
{
var httpClient = new HttpClient(new GrpcWebHandler(GrpcWebMode.GrpcWeb, new HttpClientHandler()));
var backendUrl = services.GetRequiredService<NavigationManager>().BaseUri;
var channel = GrpcChannel.ForAddress(backendUrl, new GrpcChannelOptions { HttpClient = httpClient }); return new WeatherForecastService.WeatherForecastServiceClient(channel);
});

Note: The WeatherForecastService.WeatherForecastServiceClient class is also generated automatically from the .proto file.

注意: WeatherForecastService.WeatherForecastServiceClient类也是从.proto文件自动生成的。

Step 10

第10步

Finally, add the FetchDataGrpc.razor file and make some small changes to the FetchData.razor and NavMenu.razor files. Don’t forget to make changes to the _Imports.razor file as well.

最后,添加FetchDataGrpc.razor文件,并对FetchData.razorNavMenu.razor文件进行一些小的更改。 不要忘记也对_Imports.razor文件进行更改。

Refer to the following code.

请参考以下代码。

@page "/fetchdatagrpc" 
@inject WeatherForecastService.WeatherForecastServiceClient WeatherForecastServiceClient
@using Blazorgrpc.Shared
@using Google.Protobuf.WellKnownTypes
<h1>Weather forecast</h1> <p>This component demonstrates fetching data from the gRPC service.</p> @if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td> <td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
} @code {
private IList<WeatherForecast> forecasts; protected override async Task OnInitializedAsync()
{
forecasts = (await
WeatherForecastServiceClient.GetWeatherForecastAsync(new
Empty())).Forecasts;
}
}

That’s all folks! Now, we can have fun in testing our work. After implementing the above code examples, we will get a result like the following screenshot:

那是所有人! 现在,我们可以在测试工作中获得乐趣。 在实现上述代码示例之后,我们将获得类似于以下屏幕截图的结果:

Output

We can see that both pages return the same data, but one consumes a REST service, the other consumes a gRPC service.

我们可以看到两个页面都返回相同的数据,但是一个页面使用REST服务,另一个页面使用gRPC服务。

Test them all and inspect the network traffic to see the real advantage.

对它们全部进行测试,并检查网络流量以了解真正的优势。

Network Traffic Comparison
Network Traffic Comparison
网络流量比较

In the screenshot above, you can see that the REST service has sent 55.6 KB, but the gRPC service has sent only 10.1 KB!

在上面的屏幕截图中,您可以看到REST服务已发送了55.6 KB,而gRPC服务仅发送了10.1 KB!

资源资源 (Resource)

The converted project is available in this GitHub repository.

转换后的项目位于此GitHub存储库中

结论 (Conclusion)

In this post, we have seen how to create a gRPC service in a Blazor WebAssembly-hosted application and how this solution brings significant performance benefits. This will be helpful in limited-bandwidth scenarios and will definitely speed up data transfer operations.

在本文中,我们了解了如何在Blazor WebAssembly托管的应用程序中创建gRPC服务,以及该解决方案如何带来显着的性能优势。 这将在带宽有限的情况下有所帮助,并且肯定会加快数据传输速度。

Try it out yourself and leave your feedback in the comments section below!

自己尝试一下,并在下面的评论部分中留下您的反馈!

Syncfusion Essential Studio for Blazor offers 65+ high-performance, lightweight, and responsive UI components for the web, including file-format libraries, in a single package. Please take a look at our live demos in our sample browser for a hands-on experience.

Syncfusion Essential Studio for Blazor在单个程序包中为Web提供了65个以上的高性能,轻量级和响应式UI组件,包括文件格式库。 请在示例浏览器中查看我们的现场演示,以动手体验。

For existing customers, the latest version is available for download from the License and Downloads page. If you are not yet a Syncfusion customer, you can try our 30-day free trial to check out the available features. Also, you can try our samples from this GitHub location.

对于现有客户,可从“ 许可证和下载”页面下载最新版本。 如果您还不是Syncfusion客户,则可以尝试30天免费试用,以查看可用功能。 另外,您可以从此GitHub位置尝试我们的示例。

You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!

您也可以通过我们的支持论坛Direct-Trac反馈门户与我们联系。 我们随时乐意为您提供帮助!

If you like this post, we think you will also like the following:

如果您喜欢这篇文章,我们认为您也会喜欢以下内容:

Originally published at https://www.syncfusion.com on September 2, 2020.

最初于 2020年9月2日 https://www.syncfusion.com 发布

翻译自: https://medium.com/syncfusion/10-steps-to-replace-rest-services-with-grpc-web-in-blazor-webassembly-5334394727e1

grpc与web服务共存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值