1. Dotnet9首页
  2. .NET
  3. Blazor

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

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

书接上文,昨天我们快速的走了一遍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:

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

所以时间会特别慢,尽管做了一些处理:比如官方推荐的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项目

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

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

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

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

简单解释一下:

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组件等全部拷贝到新项目:

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

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可执行文件:

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

那既然都这么熟悉了,就不用我多说了吧,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
最终选型 Blazor.Server:又快又稳!

最后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的结合体,当然,说白了就是服务端渲染。

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

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

打完收工。

原文出处:微信公众号【老张的哲学 MVP NetCore 从壹开始】

原文链接:https://mp.weixin.qq.com/s/wyuVaUTUTj_CYRKVRwqzcg

本文观点不代表Dotnet9立场,转载请联系原作者。

发表评论

登录后才能评论