如何在生产中部署 Blazor 服务器并克服 SignalR 重新连接问题?

idc*_*ife 17 blazor blazor-server-side

Blazor 服务器是一项出色的技术,但它经常因 SignalR 无法重新连接到服务器而出现故障。

如何在生产中解决这个问题?我让人们将笔记本电脑置于睡眠状态或将手机与网站连接 5 秒钟,然后“尝试重新连接”。

并且总是失败。用户等待只是为了看到“重新加载”按钮。

即使网站在移动浏览器或休眠电脑的浏览器中未处于活动状态,是否仍需要克服此问题并强制重新连接 SignalR?

Mis*_*goo 19

概述

Blazor 具有用于自定义启动过程的内置选项

为 Blazor Server 应用程序配置 SignalR 客户端

他们甚至添加了一个示例,说明如何在重新连接失败时自动重新加载

示例 - 取自当前的文档:

首先,关闭 Blazor 启动进程并autostart="false"注册您的boot.js脚本

<body>
    ...

    <div id="reconnect-modal" style="display: none;"></div>
    <script src="_framework/blazor.server.js" autostart="false"></script>
    <script src="boot.js"></script>
</body>
Run Code Online (Sandbox Code Playgroud)

然后,您可以在 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;
      },
    },
  });
})();
Run Code Online (Sandbox Code Playgroud)

  • 如果您能为这个用例添加最佳实践,那就太好了,因为这显然不适合生产。 (6认同)
  • 是的,我认为最好的链接是这个,因为它解释了任何更改的安全影响:https://learn.microsoft.com/en-us/aspnet/core/security/blazor/server?view=aspnetcore-3.1#denial -of-service-dos-攻击 (2认同)