相信很多Blazor的使用者在開發內部系統上基本上都選擇速度更快,載入更快的Blazor Server
模式。
但是Blazor Server
由於是SignalR
實現,所以在存取的時候會建立WebSocket
通道,用於js
互動和介面渲染,但是由於WebSocket
是長連線,這樣就會導致使用者在介面的時候會一直建立連結,導致伺服器寬度佔用,所以微軟預設會在無操作的情況下自動斷開連結,然後會加上該死的重新連結的一個ui,很難看,導致很多使用者看到灰色的效果。當然,微軟也提供瞭如何處理這個情況的方案,下面我們會使用微軟提供的方案解決這個問題。
Blazor Server
的空專案下面的剛剛建立的Blazor Server
的空專案。
然後長時間掛著就會出現下面這個情況。
很醜的載入ui
,灰色的全面覆蓋樣式,下面就得幹掉這個。
新增boot.js
js指令碼,用於處理重新連線
boot.js
用於自定義重新連線的操作。並且接管重新連線的程式。
(() => {
// 重試次數
const maximumRetryCount = 10000;
// 重試間隔
const retryIntervalMilliseconds = 1000;
const startReconnectionProcess = () => {
let isCanceled = false;
(async () => {
for (let i = 0; i < maximumRetryCount; i++) {
console.log(`試圖重新連線: ${i + 1} of ${maximumRetryCount}`)
await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));
if (isCanceled) {
return;
}
try {
const result = await Blazor.reconnect();
if (!result) {
// 已到達伺服器,但連線被拒絕;重新載入頁面。
location.reload();
return;
}
// 成功重新連線到伺服器。
return;
} catch {
//沒有到達伺服器;再試一次。
}
}
// 重試次數太多;重新載入頁面。
location.reload();
})();
return {
cancel: () => {
isCanceled = true;
},
};
};
let currentReconnectionProcess = null;
Blazor.start({
configureSignalR: function (builder) {
let c = builder.build();
c.serverTimeoutInMilliseconds = 30000;
c.keepAliveIntervalInMilliseconds = 15000;
builder.build = () => {
return c;
};
},
reconnectionHandler: {
onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
onConnectionUp: () => {
currentReconnectionProcess?.cancel();
currentReconnectionProcess = null;
},
},
});
})();
修改Pages/_Host.cshtml
@page "/"
@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp1.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
<link href="BlazorApp1.styles.css" rel="stylesheet" />
<link rel="icon" type="image/png" href="favicon.png"/>
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
發生錯誤。此應用程式在重新載入之前可能不再響應。
</environment>
<environment include="Development">
發生了一個未處理的異常。詳細資訊請參見瀏覽器開發工具。
</environment>
<a href="" class="reload">重新載入</a>
<a class="dismiss">