Skip to content

HTTP Transfers

  • GitHub stars for shinyorg/shiny
  • NuGet downloads for Shiny.Net.Http
  • NuGet downloads for Shiny.Net.Http.Blazor
Operating Systems
Android
iOS
Windows
macOS
Linux
Web

Shiny HTTP Transfers enables background uploads and downloads that continue even when your app is suspended. On iOS/Android, transfers are managed by the OS and will resume after app restarts. On Windows, Linux, macOS, and plain .NET hosts a managed HttpClient loop drives transfers and supports resumable downloads via HTTP Range requests. On Blazor WebAssembly, transfers are queued to IndexedDB and drained by a Service Worker via the Background Sync API.

  • Background uploads and downloads
  • Multipart and raw upload support
  • Progress tracking with speed and ETA
  • Automatic resume after app restart
  • Resumable downloads on plain .NET (Linux/macOS/Windows) via HTTP Range requests
  • Metered/unmetered network control
  • Managed transfer list for UI binding
  • Cross-platform: iOS, Android, Windows, Linux, macOS, Blazor WebAssembly
PlatformPackageBacking
iOSShiny.Net.HttpNSURLSession background session
AndroidShiny.Net.HttpForeground service + WorkManager
WindowsShiny.Net.HttpManaged HttpClient loop
Linux / macOS / Plain .NETShiny.Net.HttpManaged HttpClient + IConnectivity loop; resumable downloads via HTTP Range
Blazor WebAssemblyShiny.Net.Http.BlazorService Worker Background Sync + IndexedDB; downloads not resumable
Shiny.Net.HttpNuGet package Shiny.Net.Http
Shiny.Hosting.MauiNuGet package Shiny.Hosting.Maui

Implement IHttpTransferDelegate to handle transfer completion and errors in the background.

public partial class MyTransferDelegate : IHttpTransferDelegate
{
readonly ILogger<MyTransferDelegate> logger;
public MyTransferDelegate(ILogger<MyTransferDelegate> logger)
{
this.logger = logger;
}
public Task OnCompleted(HttpTransferRequest request)
{
this.logger.LogInformation("Transfer completed: {Id}", request.Identifier);
return Task.CompletedTask;
}
public Task OnError(HttpTransferRequest request, int statusCode, Exception ex)
{
this.logger.LogError(ex, "Transfer failed: {Id}, Status: {Status}", request.Identifier, statusCode);
return Task.CompletedTask;
}
}

On Android, background transfers run as a foreground service. Customize the notification:

#if ANDROID
public partial class MyTransferDelegate : IAndroidForegroundServiceDelegate
{
public void Configure(AndroidX.Core.App.NotificationCompat.Builder builder)
{
builder
.SetContentTitle("My App")
.SetContentText("Transferring files...")
.SetSmallIcon(Resource.Mipmap.appicon);
}
}
#endif
// iOS / Android / Windows / Linux / macOS / plain .NET
services.AddHttpTransfers<MyTransferDelegate>();
// Blazor WebAssembly
services.AddBlazorHttpTransfers<MyTransferDelegate>(opts =>
{
// Optional — defaults to the bundled Shiny service worker
opts.ServiceWorkerPath = "./_content/Shiny.Net.Http.Blazor/http-transfer-sw.js";
});

On Blazor, ship the bundled SW at the configured path, or import its handlers from your own service worker:

my-sw.js
importScripts('./_content/Shiny.Net.Http.Blazor/http-transfer-sw.js');
claude plugin marketplace add shinyorg/skills
claude plugin install shiny-client@shiny

Coming soon — Copilot plugin install instructions will be added here.

View shiny-client Plugin