30

最终选型 Blazor.Server:又快又稳!

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzAwNTMxMzg1MA%3D%3D&%3Bmid=2654078630&%3Bidx=3&%3Bsn=8781d672c565050e485a45c48a94a584
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

nMF3quE.png!web

书接上文,昨天我们快速的走了一遍wasm的开发流程( 我的『MVP.Blazor』快速创建与部署 ),总体来说还是很不错的,无论是从技术上,还是从开发上,重点是用 C#来开启前端时代,可以开发SPA单页面应用 ,这个本身就是很奇妙的一件事,因为我有一定的VUE.JS基础,所以入手Blazor.Wasm的话,还是特别快的,可以说是很对脾气的,无论是双向绑定、组件开发、页面模板、生命周期、父子通讯等等等等上,都很契合。

所以说:只要你会ASP.NETCore和Vue(当然其他的也可以)技术,入门Blazor也就一两天的事儿。不过在最后一步——托管和部署的时候,出现了一个小问题,当然,也不是问题,是我没有考虑到的,下边说一下这个小问题。

1、为什么要选择Blazor.Server?

上边我已经说过了,Blazor.Wasm开发起来还是很舒服的,而且也是SPA单页面应用程序,这里先说下两者的区别:

Blazor 技术又分两种:

  • Blazor WebAssembly

  • Blazor Server

Blazor WebAssembly 是真正的SPA,页面的渲染在前端实现,可以实现真正的前后端分离设计。而Blazor.Server可以认为是前者的服务端渲染版本,它使用SignalR实现了客户端的实时通讯,它的计算跟渲染都在服务端处理。

你可以看明白了吧,其实wasm就像是vue那种单页面程序,而Blazor.Server更像是基于前者的一种服务端渲染( 注意:和MVC不是一回事 ),第一次刷新是HTTP请求,平时点击是SignalR处理。

虽然看似wasm有友好,但是部署的时候出现了一个问题,就是它是可以直接在浏览器中执行,就是WebAssembly在浏览器里实现了一个.NET Runtime,所以每次刷新的时候,都会加载全部的资源程序集文件dll:

jQnMnua.png!web

所以时间会特别慢,尽管做了一些处理:比如官方推荐的PWA技术(可以在客户端缓存部分dll),也做了竞速,然后还有压缩,当然,还有人说可以使用CDN,额,好像开发一个SPA程序做了这么多步骤,显然不是很美味,可能我道行不够吧。

最后,纠结了纠结,还是选择了Blazor.Server,同时也看到上篇文章中,有小伙伴留言,更加速了我转型Server的劲头:

貌似目前blazor wasm的项目加载都非常慢,我还是优先选择blazor server,微软吹在2c4g的服务器上部署blazor server能承载十几万个session,学过Angular用blazor server特别有亲切感,service,component,DI,理念都很一致

是不是看着很心动,那果断用起来,其实我主要是想解决这个刷新很慢的问题。

好啦,正式开始将项目从wasm迁移到blazor.server中。

2、代码迁移

因为昨天已经说过了wasm的创建过程,而且代码也都写好了,特别是.razor页面 ,几乎都不用做处理,直接copy就行,那我就说说注意点。

1、创建server项目

还是昨天的那个页面,只不过是第一个选项了:

zya6r2n.png!web

创建完成后,可以看到默认的项目结构,和ASP.NETCore的web项目很像:

JFRNzaU.png!web

简单解释一下:

1、wwwroot:静态资源文件;

2、Data:数据文件(M),定义Model和Service,可以从数据库里获取数据;

3、Pages:视图(V)和逻辑(VM),和wasm一样;

4、Shared:共享组件;

5、_Imports.rzor:命名空间导入;

6、App.razor:项目文件;

7、appsettings.json:配置文件;

8、Program.cs:程序总运行入口;

9、Startup.cs:启动类,做注入和中间件配置;

是不是感觉和ASP.NETCore项目很像 ,本来就是,看Framworks框架就知道了,反正只要是你玩儿过netcore,昨天对wasm也有一定的了解的话,对项目结构还是比较熟络的,接下来就是开发了。

2、默认示例解析

这次官方给的还是三个例子:事件绑定计数器、数据获取、首页加载。

除了这三个外,有一个需要注意的是,之前我们使用wasm的时候,是一个SPA,需要提供一个index.html文件,作为整个项目的项目承载页面,现在我们使用了server服务端渲染后,就不需要了,转而使用了一个_Host.cshtml的页面,从后缀名可以看出来,其实也和html很像的一个cshtml页面,而不是.razor。

那下边简单说下获取数据FetchData:

之前我们使用wasm的时候,因为是前后端分离,所以使用的是HttpClient来远程获取资源服务器的资源数据,但是现在我们使用了服务端以后,可以自己写业务逻辑了:

比如增删改查,持久化等等逻辑:

正如示例的,定义了一个WeatherForecastService.cs服务,然后注入到页面

@inject WeatherForecastService ForecastService

接着就可以直接使用了:

@code {

private WeatherForecast[] forecasts;


protected override async Task OnInitializedAsync()

{

forecasts = await ForecastService.GetForecastAsync(DateTime.Now);

}

}

但是我今天不打算用这个逻辑,因为我还是想要使用Blog.Core的数据,所以,还是打算使用HttpClient来获取远程数据,而不是自写逻辑。

那下边就开始迁移:

3、代码COPY

为了让大家能看到两个项目,所以我直接在之前的解决方案中,创建一个新项目:

Blog.MVP.Blazor.SSR

将wwwroot资源文件,Common公共类,Models模型,Pages页面,Shared组件等全部拷贝到新项目:

iq2Ufei.png!web

4、修改Data获取方式

因为默认的server采用的是service的方式,我们要使用httpclient的方式,所以需要简单做下修改:

添加nuget包

<PackageReference Include="System.Net.Http.Json" Version="3.2.0" />

命名空间引入_import

@using System.Net.Http.Json

服务注册到容器startup.cs

services.AddSingleton<HttpClient>();

用绝对路径发起api请求

await Http.GetFromJsonAsync<MessageModel<PageModel<BlogArticle>>>

("http://apk.neters.club/api/Blog?page=1&bcategory=MVP_azure_2020&intPageSize=20");

因为现在是服务端的请求, 所以不用配置跨域

5、调试

之前wasm调试的时候,我们通过console.write(),会把结果打印到浏览器的控制台,

但是现在我们可以直接输出到程序的控制台dos窗口。

两个都很方便。

好啦,到这里我们就迁移完成了,接下来我们就托管部署下吧。

3、新的托管与部署

还记得昨天我们是怎么部署的么?

因为wasm是SPA,所以我们发布后,直接wwwroot部署到nginx,作为一个静态站点即可,就像是部署build后的vue那样。

代码发布

但是Blazor.Server不一样了,毕竟是SSR渲染。我们把项目进行发布,可以看到发布后的文件和之前的ASP.NETCore真的一样,还有.exe可执行文件:

aiENJfj.png!web

那既然都这么熟悉了,就不用我多说了吧,Linux+PM2+Nginx跨平台流程走起!

Linux部署

我直接写了要给.sh文件,这样在服务器里部署,不用FTP,浪费带宽

git pull;

rm -rf .PublishFiles;

dotnet build;

cd Blog.MVP.Blazor.SSR

dotnet publish -o /home/Blog.MVP.Blazor/Blog.MVP.Blazor.SSR/bin/Debug/netcoreapp3.1/publish;

cp -r /home/Blog.MVP.Blazor/Blog.MVP.Blazor.SSR/bin/Debug/netcoreapp3.1/publish /home/Blog.MVP.Blazor/.PublishFiles;

echo "Successfully!!!! ^ please see the file .PublishFiles";

然后检查无误后,通过pm2守护进程

pm2 start "dotnet Blog.MVP.Blazor.SSR.dll" --name mvp.dll

uyEjmme.png!web

最后nginx代理

server {

listen 80;

server_name mvp.neters.club;

rewrite ^(.*)$ https://$host$1 permanent;

#charset koi8-r;

#access_log logs/host.access.log main;

location / {

root html;

index index.html index.htm;

}

}


server {

listen 443 ssl;

server_name mvp.neters.club;

ssl_certificate /etc/nginx/conf.d/1_mvp.neters.club_bundle.crt;

ssl_certificate_key /etc/nginx/conf.d/2_mvp.neters.club.key;

ssl_session_timeout 5m;

ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;

ssl_prefer_server_ciphers on;

location / {

proxy_pass http://localhost:5050;

index index.php index.html index.htm;

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection keep-alive;

proxy_set_header Host $host;

proxy_cache_bypass $http_upgrade;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

}

}

检查nginx是否正常

nginx -t

重启nginx服务

nginx -s reload

搞定,可以在线查看效果。

5、总结

https://mvp.neters.club/

通过查看重新发布的项目,可以看到速度已经基本能接受了。

总体来说,Blazor.Server简直就是Blazor.Wasm和ASP.NetCore的结合体,当然,说白了就是服务端渲染。

我更喜欢的,还是它的组件开发,

双向绑定、组件开发、组件继承、页面模板、生命周期、父子通讯
很有前端开发那味,当然还有很多其他的亮点知识,等待一起发掘。

打完收工。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK