Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent a Blazor Server webapp from needing refresh after device standby?

I have a Blazor Server WebApp that is being used by desktop clients (via browser) and mobile android PDA, mostly through local LAN. However, sometimes the PDAs go in standby and when they are waken the page must be refreshed or it will not respond. There is a way to avoid that? I whould like that the users should be able to use the WebApp as soon as the PDAs is waken from standby, without the need of refresh.

I have configured the services in this way:

services.AddRazorPages();
services.AddServerSideBlazor()
.AddHubOptions(options =>
 {
     options.ClientTimeoutInterval = TimeSpan.FromMinutes(120);
     options.KeepAliveInterval = TimeSpan.FromSeconds(15);
 });

Any suggestion? Thanks in advance!

like image 452
Dany Avatar asked Dec 20 '25 14:12

Dany


1 Answers

The best solution for this is Blazor PWA or WebAssembly. In these modes the connection to the server can be maintained and established in the background. The specific use case for WebAssembly is to support intermittent connections and offline operations.

Which Blazor hosting model should I choose?

If the device has gone into standby, then we start to talk about potentially very long refresh cycles. Once the server connection is severed, the server will retain it for a brief period of time, but once all the backend is torn down, the only viable way to reconnect is to refresh the page.

You could also look into lengthening these timeouts, but as a general rule we don't try to support retentions and timeouts into hours as that would not be very scalable, but it might solve your immediate problem: Server-side circuit handler options

Option Default Description
DetailedErrors false Send detailed exception messages to JavaScript when an unhandled exception occurs on the circuit or when a .NET method invocation through JS interop results in an exception.
DisconnectedCircuitMaxRetained 100 Maximum number of disconnected circuits that the server holds in memory at a time.
DisconnectedCircuitRetentionPeriod 3 minutes
JSInteropDefaultCallTimeout 1 minute
MaxBufferedUnacknowledgedRenderBatches 10 Maximum number of unacknowledged render batches the server keeps in memory per circuit at a given time to support robust reconnection. After reaching the limit, the server stops producing new render batches until one or more batches are acknowledged by the client.

I'm not sure how effective this is for devices that resume from standby, but there is the office guidance for Automatically refresh the page when server-side reconnection fails

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;
      }
    }
  });
})();
like image 155
Chris Schaller Avatar answered Dec 23 '25 04:12

Chris Schaller



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!