【问题标题】:How to deploy Blazor server in production and overcome SignalR re-connection problems?如何在生产中部署 Blazor 服务器并克服 SignalR 重新连接问题?
【发布时间】:2020-05-18 18:29:02
【问题描述】:

Blazor 服务器是一项了不起的技术,但它经常因 SignalR 无法重新连接到服务器而中断。

如何在生产中解决这个问题?我让人们让他们的笔记本电脑处于睡眠状态或将手机与网站放在一起 5 秒钟,而不是 - “尝试重新连接”。

而且总是失败。用户正在等待看到“重新加载”按钮。

即使网站在移动浏览器或睡眠电脑的浏览器中未激活,也能克服此问题并强制重新连接 SignalR?

【问题讨论】:

  • 帮自己一个忙,使用 Blazor Webassembly。自 2020 年 5 月,版本 3.2.0,.NET Core 3.1 开始,它已准备好生产
  • Blazor WebAssembly 很棒,但并不适合所有可能的用例。

标签: blazor blazor-server-side


【解决方案1】:

概述

Blazor 已经内置了用于自定义启动过程的选项,但它们的文档并没有很好地记录。

据我所知,这就是:Configure the SignalR client for Blazor Server apps

但是还有更多选项,包括设置重新连接选项的能力。

示例

在下面的代码示例中,我设置了 maxRetries 和 retryIntervalMilliseconds(第 48/49 行)——它们定义了客户端在通信中断时尝试重新连接的积极程度。

我还配置了一个自定义 reconnectionHandler(第 51 行),其最小实现将尝试重新连接(不显示任何 UI),如果所有尝试都失败,它将简单地重新加载页面。

这不是一件特别聪明的事情,但它可以作为一个示例来演示您如何自定义流程。

进一步阅读 AspNetCore Circuits Client Side Code

** 请不要在生产中使用此示例 - 它仅用于说明 **

首先,使用autostart="false" 关闭 Blazor 启动过程
<script autostart="false" src="_framework/blazor.server.js"></script>
然后,您可以提供自己的连接处理程序和设置
<script>
    async function connectionDown(options) {
        console.log("Connection Down - you could do some UI here...");
        for (let i = 0; i < options.maxRetries; i++) {
            console.log("Waiting for reconnect attempt #"+(i+1)+" ...");
            await this.delay(options.retryIntervalMilliseconds);
            if (this.isDisposed) {
                break;
            }

            try {
                // reconnectCallback will asynchronously return:
                // - true to mean success
                // - false to mean we reached the server, but it rejected the connection (e.g., unknown circuit ID)
                // - exception to mean we didn't reach the server (this can be sync or async)
                console.log("Starting Reconnect attempt #"+(i+1)+" ...");
                const result = await window.Blazor.reconnect();
                if (!result) {
                    // If the server responded and refused to reconnect, log it 
                    console.error("Server Rejected");
                } else {
                    // Reconnected!
                    return;
                }
            } catch (err) {
                // We got an exception so will try again 
                console.error(err);
            }
        }
        // all attempts failed - let's try a full reload
        // This could be a UI change instead or something more complicated
        location.reload();
    }

    function delay(durationMilliseconds) {
        return new Promise(resolve => setTimeout(resolve, durationMilliseconds));
    }

    function connectionUp(e) {
        // Reconnected
        console.log("Connection UP!");
        // if you have a UI to hide/change you can do that here.
    }

    window.Blazor.start({
        reconnectionOptions: {
            maxRetries: 30,
            retryIntervalMilliseconds: 500,
        },
        reconnectionHandler: {
            onConnectionDown: e => connectionDown(e),
            onConnectionUp: e => connectionUp(e)
        }
    });
</script>

【讨论】:

  • 您好!非常感谢您提供示例的好答案!这将有很大帮助!当我尝试实现自己的重新连接时,我想知道,Blazor 团队是否编写了自己的重新连接代码,但由于某种原因会中断?我的意思是我怀疑他们有像你写的东西,重新连接和页面重新加载。但是由于某种原因,他们的代码总是碰巧无法重新连接。 1-2 秒没有互联网,并且 blazor 服务器端 js 已死,无法连接。就像它不识别服务器或其他东西一样,忘记了它。我会尝试自己编写和调试
  • 有重新连接代码,但它不会自动重新加载。服务端也有设置电路可以断开多长时间才被处理掉。
  • 您是否偶然知道可以在 blazor 服务器的哪个位置进行配置?在 Startup.cs 的某个地方?
  • 是的,我认为最好的链接是这个链接,因为它解释了任何更改的安全影响:docs.microsoft.com/en-us/aspnet/core/security/blazor/…
  • 如果您可以为此用例添加最佳实践,那就太好了,因为这显然不适合生产。
猜你喜欢
  • 2018-12-13
  • 2022-12-03
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 2013-12-11
  • 2021-03-09
  • 2015-11-12
  • 1970-01-01
相关资源
最近更新 更多