Blazor WebAssembly + Grpc Web=未来?

Blazor WebAssembly是什么

首先来说说WebAssembly是什么,WebAssembly是一个可以使C#,Java,Golang等静态强类型编程语言,运行在浏览器中的标准,浏览器厂商基于此标准实现执行引擎。

在实现了WebAssembly标准引擎之后,浏览器中可以执行由其他语言编译成的wasm模块。使用强类型编程语言的好处显而易见:

  • 可以选择更多的语言,编写前端逻辑

  • 静态编程语言编译成的字节码,相对于JS这种脚本语言执行效率更高

  • 可以使用静态编程语言生态中的强大类库

Blazor WebAssembly是dotnet版本的WebAssembly实现,微软将dotnet运行时编译成dotnet.wasm模块,我们的程序编译出来的dll文件运行在此模块上。

需要注意的是,Blazor WebAssembly是一个完完全全的前端框架,只是逻辑代码不再使用JS编写,而是使用C#编写。

Grpc Web是什么

Grpc是一种与语言无关的的高性能远程过程调用(RPC)框架。Grpc有以下优点

  • 现代高性能轻量级 RPC 框架。

  • 协定优先 API 开发,默认使用协议缓冲区,允许与语言无关的实现。

  • 可用于多种语言的工具,以生成强类型服务器和客户端。

  • 支持客户端、服务器和双向流式处理调用。

  • 使用 Protobuf 二进制序列化减少对网络的使用。

而Grpc Web是Grpc的前端实现版本,可以使浏览器应用直接与Grpc交互。

有了Grpc Web,我们可以直接在Blazor WebAssembly中调用Grpc Server,而不用再通过传统的Http请求方法调用。

代码演示

GrpcServer

首先需要新建一个Grpc Server

e2c11fcf1afe3dfd0122c62998a2ddbb.png

 然后为其引入 Grpc.AspNetCore.Web Nuget包,并开启grpc web

1ac0db1151424ad7562ea45b83cf87bb.png

app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints// Configure the HTTP request pipeline.app.MapGrpcService<GreeterService>().EnableGrpcWeb();

之后我们需要为Grpc Server开启跨域设置,允许跨域访问

app.Use(async (context, next) =>{context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");context.Response.Headers.Add("Access-Control-Allow-Headers", "*");context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH");context.Response.Headers.Add("Access-Control-Allow-Origin", "*");context.Response.Headers.Add("Access-Control-Max-Age", "100000");context.Response.Headers.Add("Access-Control-Expose-Headers", "Grpc-Status,Grpc-Message,Grpc-Encoding,Grpc-Accept-Encoding");    if (context.Request.Method.ToUpper() == "OPTIONS"){        return;}    // Do work that can write to the Response.await next.Invoke();    // Do logging or other work that doesn't write to the Response.});

最终Program.cs的代码如下

using GrpcService2.Services;var builder = WebApplication.CreateBuilder(args);builder.Services.AddGrpc();var app = builder.Build();
app.Use(async (context, next) =>{context.Response.Headers.Add("Access-Control-Allow-Credentials", "true");context.Response.Headers.Add("Access-Control-Allow-Headers", "*");context.Response.Headers.Add("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS,HEAD,PATCH");context.Response.Headers.Add("Access-Control-Allow-Origin", "*");context.Response.Headers.Add("Access-Control-Max-Age", "100000");context.Response.Headers.Add("Access-Control-Expose-Headers", "Grpc-Status,Grpc-Message,Grpc-Encoding,Grpc-Accept-Encoding");    if (context.Request.Method.ToUpper() == "OPTIONS"){        return;}    await next.Invoke();
});app.UseGrpcWeb();
app.MapGrpcService<GreeterService>().EnableGrpcWeb();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();

Blazor WebAssembly

现在新建一个WebAssembly项目

21efc3d178192c9a0a23ffb53ffd937a.png

 为其引入以下nuget包

<ItemGroup><PackageReference Include="Google.Protobuf" Version="3.20.1" /><PackageReference Include="Grpc.Net.Client" Version="2.46.0" /><PackageReference Include="Grpc.Net.Client.Web" Version="2.46.0" /><PackageReference Include="Grpc.Tools" Version="2.46.1"><IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets><PrivateAssets>all</PrivateAssets></PackageReference></ItemGroup>

在其项目文件中包含进proto文件

<ItemGroup><Protobuf Include="..\GrpcService2\Protos\*.proto" GrpcServices="Client" /></ItemGroup>

然后将GrpcClient注入容器

builder.Services.AddScoped(p =>
{var channel = GrpcChannel.ForAddress("https://localhost:7033/", new GrpcChannelOptions{HttpHandler = new GrpcWebHandler(new HttpClientHandler())});var client = new GrpcService2.Greeter.GreeterClient(channel);return client;
});

修改Index.razor,让其访问grpc server

@page "/"
@inject GrpcService2.Greeter.GreeterClient GreeterClient<div>grpc web response @Message</div>@code {public string Message { get; set; }protected override async Task OnInitializedAsync(){var reply = await GreeterClient.SayHelloAsync(new GrpcService2.HelloRequest { Name = "test" });Message = reply.Message;}
}

最终效果如下

f34437ded065558197854dafb7c5440c.png

可以看到整个请求/渲染过程,使用的是C#代码编写的逻辑,没用到js,原理是因为,blazor webassembly将我们的dotnet运行时,与我们的代码编译后的程序集,运行在了基于webassembly标准实现的浏览器引擎中。

77c3d5f94b72056c8bdd6425c95f5ec0.png

并且可以看到基于Grpc Web的请求响应体都使用的压缩过的二进制形式。效率相对更高

62addb7310160912fd4f83b4d361d89e.png 

daba12faafb07b781492c7b492017354.png

webassembly难道是未来?难道未来的某一天要和js say goodbye了吗?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/286075.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Can't create directory 'E:\Repositories\***\db\transactions\138-41.txn':

遇到这种问题应该是迁移SVN库时丢失了文件夹引起的&#xff0c;直接在服务器上找到对应项目的db文件夹&#xff0c;手动创建“transactions”目录和“txn-protorevs”目录即可正常提交。

【MATLAB统计分析与应用100例】案例013:matlab读取Excel数据,调用nlinfit函数作一元非线性回归

1. 一元线性回归分析效果预览 2. matlab完整实现代码 %读取数据,绘制散点图** HeadData = xlsread(examp08_02.xls); %从Excel文

发布功能完成02《ivx低代码签到系统制作》

制作iVX 低代码项目需要进入在线IDE&#xff1a;https://editor.ivx.cn/ 一、发布功能思考、数据库、服务创建 上一节我们制作了后台的页面&#xff0c;那么此时我们应该需要制作发布功能了&#xff0c;那么在制作之前&#xff0c;我们应该思考一下如何制作这个签到内容发布的…

WPF 实现简易北京地铁效果图

本文经原作者授权以原创方式二次分享&#xff0c;欢迎转载、分享。原文作者&#xff1a;眾尋原文地址&#xff1a; https://www.cnblogs.com/ZXdeveloper/p/8600785.html前言这个是百度地图上北京地铁的地址&#xff0c;我们先看下百度上面的效果图&#xff1b;我要实现的内容比…

C#学习笔记-Windows窗体自定义初始位置

根据屏幕大小定义初始位置&#xff1a; &#xff08;这个不是难&#xff0c;但是最近常常忘记&#xff0c;记着方便查看。&#xff09; 1 //获取当前屏幕的长和宽2 int ScreenX Screen.PrimaryScreen.Bounds.Width;3 int ScreenY Screen…

【MATLAB统计分析与应用100例】案例014:matlab读取Excel数据,调用stepwise函数作交互式逐步回归分析

文章目录 1. 交互式逐步回归分析结果预览2. 完整matlab代码1. 交互式逐步回归分析结果预览 2. 完整matlab代码 % 从Excel文件examp08_03.xls中读取数值型数据 xydata = xlsread(examp08_03.xls); y = xydata<

MsSql 自定义分数段,按分数段统计考试人次

--分数段分布 DECLARE levels VARCHAR(100) 10,20,30,40,50,60,70,80,90,100; --自定义分数段 DECLARE paperId VARCHAR(100)0000000000001019--试卷编号 WITH tbTemp AS (--处理分数段SELECT L.levelFROM (SELECT [value] CONVERT(XML, <v> REPLACE(levels, ,, &l…

opencv---颜色空间转化并实现物体跟踪

一、图像处理的基本操作 因为这是第一篇写opencv的笔记&#xff0c;故先讲讲在python下写opencv的基本操作。总共总结了三点如下&#xff1a; 开头一定要加编码声明:-*- coding: utf-8 -*-python下记得引入opencv模块:import cv2要知道如何读取并展示图片,代码如下:# -*- codin…

签到功能完成03《ivx低代码签到系统制作》

制作iVX 低代码项目需要进入在线IDE&#xff1a;https://editor.ivx.cn/ 一、签到页制作 上一节完成了签到内容的发布&#xff0c;那我们接下来如何制作一个签到页面并且签到呢&#xff1f; 此时我们先创建一个页面叫做签到二维码页面&#xff1a; 随后直接预览这个页面&am…

System.CommandLine参数Argument

前两篇说到Command和Option&#xff0c;这篇说说Argument。Argument的用法和Option很像&#xff0c;只是他的构造和属性有些差别&#xff0c;再就是在运行输入时有区别&#xff0c;接下来看看实现。一个参数//创建根命令 var rootCommand new RootCommand("这是一个命令行…

Kotlin和Java混合开发总结(基于Kotlin1.3.0版本)

我本来是不想学习kotlin的&#xff0c;但是现在的形势&#xff0c;很多公司都在使用kotlin开发&#xff0c;可以说学会kotlin也是无奈之举&#xff0c;既然是潮流&#xff0c;谷歌也在大力推广&#xff0c;所以还是只能硬着头皮逼迫自己学一下&#xff0c;也能更快适应公司的需…

【MATLAB统计分析与应用100例】案例015:matlab读取Excel数据,进行值聚类分析

1. 聚类分析轮廓图 2. matlab完整代码 %*****计算例9.1的距离矩阵 x = [1, 2, 6, 8, 11];

01超精美渐变色动态背景完整示例【CSS动效实战(纯CSS与JS动效)】

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 本节案例如下&#xff08;其他动效篇幅原因逐步讲解&#xff0c;欢迎三…

Liferay 用本地私服(nexus) 打包部署Portlet应用

当我们使用搭建一个nexus本地仓库&#xff0c;并且配置settings.xml来让应用启用这个仓库。我们使用Liferay 6.1.10的archetype来创建liferay portlet, 如下图&#xff1a; 当我们运行命令mvn package liferay:deploy时&#xff0c;会出现以下错误&#xff1a; [DEBUG] Using c…

【MATLAB统计分析与应用100例】案例016:matlab读取Excel数据,进行样品系统聚类分析

1. 聚类分析结果 2. matlab完整代码 (1)读取数据,并进行标准化 [X,textdata] = xlsread(examp09_02.xls); % 从Excel文件中读取数据 X = zscore(X

解决React Native报错:Error:Found unexpected optical bounds (red pixel)

问题背景 同样是在升级 gradle plugin V2.2.3 --> gradle plugin V3.0.1后&#xff0c;运行至打包APK期间报错&#xff1a; Error:found unexpected optical bounds (red pixel) on top border at x14.&#xff08;错误&#xff1a;在X14的上边框上发现意外的光学边界&am…

webpack 入门

什么是WebPack&#xff0c;为什么要使用它&#xff1f; 为什要使用WebPack 现今的很多网页其实可以看做是功能丰富的应用&#xff0c;它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度&#xff0c;前端社区涌现出了很多好的实践方法 模块化&#xff0c;让我…

使用vsftp虚拟用户实现安全访问控制

一、ftp连接方式 1、命令连接 ftp在与用户交互时&#xff0c;首先打开的是TCP的21号端口&#xff0c;建立命令连接&#xff0c;这个连接会始终存在&#xff0c;直到用户输入bye的那一刻&#xff0c;才断开命令连接。 2、数据连接 1&#xff09;主动连接 主动连接是基于TCP21号端…

【前端就业课 第二阶段】CSS 零基础到实战(04)定位

若是大一学子或者是真心想学习刚入门的小伙伴可以私聊我&#xff0c;若你是真心学习可以送你书籍&#xff0c;指导你学习&#xff0c;给予你目标方向的学习路线&#xff0c;无套路&#xff0c;博客为证。 一、定位 定位分为相对定位以及绝对定位。 相对定位可以理解为在 HTM…

Android TextView设置ClickableSpan 点击结尾空白位置也响应点击的问题

解决办法&#xff0c;在后边紧接着追加一个0宽度字符&#xff1a; builder.append("\u200b"); 相关知识&#xff1a; “\u200b” 为 Unicode Character ‘ZERO WIDTH SPACE’ (U200B)&#xff0c;可用于内容标识&#xff0c;不占位数&#xff08;宽度0&#xff0…