我有一个 Blazor Server WebApp,可供桌面客户端(通过浏览器)和移动 Android PDA 使用,主要通过本地 LAN。 然而,有时 PDA 会进入待机状态,当它们被唤醒时,必须刷新页面,否则不会响应。 有办法避免吗?我希望用户能够在 PDA 从待机状态唤醒后立即使用 WebApp,而不需要刷新。
我是这样配置服务的:
services.AddRazorPages();
services.AddServerSideBlazor()
.AddHubOptions(options =>
{
options.ClientTimeoutInterval = TimeSpan.FromMinutes(120);
options.KeepAliveInterval = TimeSpan.FromSeconds(15);
});
有什么建议吗? 预先感谢!
最好的解决方案是 Blazor PWA 或 WebAssembly。在这些模式下,可以在后台维护和建立与服务器的连接。 WebAssembly 的具体用例是支持间歇性连接和离线操作。
如果设备已进入待机状态,那么我们就开始讨论可能很长的刷新周期。一旦服务器连接被切断,服务器会保留一小段时间,但一旦所有后端都被拆除,重新连接唯一可行的方法就是刷新页面。
您也可以考虑延长这些超时,但作为一般规则,我们不会尝试支持保留和超时到小时,因为这不太可扩展,但它可能会解决您眼前的问题:服务器端电路处理程序选项
选项 | 默认 | 描述 |
---|---|---|
详细错误 | 假 | 当电路上发生未处理的异常或通过 JS 互操作调用 .NET 方法导致异常时,向 JavaScript 发送详细的异常消息。 |
DisconnectedCircuitMaxRetained | 100 | 服务器一次在内存中保存的最大断开电路数。 |
断开电路保留期 | 3 | 分钟 |
JSInteropDefaultCallTimeout | 1 | 分钟 |
最大缓冲未确认渲染批次 | 10 | 服务器在给定时间在每个电路的内存中保留的未确认渲染批次的最大数量,以支持稳健的重新连接。达到限制后,服务器将停止生成新的渲染批次,直到客户端确认一个或多个批次。 |
我不确定这对于从待机状态恢复的设备有多有效,但是有办公室指南 服务器端重新连接失败时自动刷新页面
wwwroot/boot.js
(() => {
const maximumRetryCount = 3;
const retryIntervalMilliseconds = 5000;
const reconnectModal = document.getElementById('reconnect-modal');
const startReconnectionProcess = () => {
reconnectModal.style.display = 'block';
let isCanceled = false;
(async () => {
for (let i = 0; i < maximumRetryCount; i++) {
reconnectModal.innerText = `Attempting to reconnect: ${i + 1} of ${maximumRetryCount}`;
await new Promise(resolve => setTimeout(resolve, retryIntervalMilliseconds));
if (isCanceled) {
return;
}
try {
const result = await Blazor.reconnect();
if (!result) {
// The server was reached, but the connection was rejected; reload the page.
location.reload();
return;
}
// Successfully reconnected to the server.
return;
} catch {
// Didn't reach the server; try again.
}
}
// Retried too many times; reload the page.
location.reload();
})();
return {
cancel: () => {
isCanceled = true;
reconnectModal.style.display = 'none';
},
};
};
let currentReconnectionProcess = null;
Blazor.start({
reconnectionHandler: {
onConnectionDown: () => currentReconnectionProcess ??= startReconnectionProcess(),
onConnectionUp: () => {
currentReconnectionProcess?.cancel();
currentReconnectionProcess = null;
}
}
});
})();