Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/lostbeard/blazorserviceworkerdemo
This Blazor WASM demos using a Blazor WASM ServiceWorker!
https://github.com/lostbeard/blazorserviceworkerdemo
blazor blazor-webassembly csharp dotnet multithreading service-worker webassembly
Last synced: about 2 months ago
JSON representation
This Blazor WASM demos using a Blazor WASM ServiceWorker!
- Host: GitHub
- URL: https://github.com/lostbeard/blazorserviceworkerdemo
- Owner: LostBeard
- License: mit
- Created: 2023-10-19T20:27:25.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-08-07T01:34:12.000Z (5 months ago)
- Last Synced: 2024-08-07T03:55:52.804Z (5 months ago)
- Topics: blazor, blazor-webassembly, csharp, dotnet, multithreading, service-worker, webassembly
- Language: C#
- Homepage: https://lostbeard.github.io/BlazorServiceWorkerDemo/
- Size: 19.3 MB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Blazor WASM ServiceWorker Demo
Blazor WASM running as your ServiceWorker! Thanks to [SpawnDev.BlazorJS.WebWorkers](https://github.com/LostBeard/SpawnDev.BlazorJS#spawndevblazorjswebworkers) it is now possible to run Blazor WASM in all browser Worker contexts: DedicatedWorker, SharedWorker, and ServiceWorker.
[Live Demo](https://lostbeard.github.io/BlazorServiceWorkerDemo/)
The live demo is nothing special at the moment. In Chrome you can see the Blazor messages from the worker handler handling events. Firefox ServiceWorker console can be found at "about:debugging#/runtime/this-firefox"
This code demonstrates loading a Blazor WASM inside a ServiceWorker context and handling any events a ServiceWorker may want. Like install, fetch, push, sync, etc.
This is currently a working proof of concept and likely to change. Any and all feedback is welcome!
This project relies on a couple of my other projects [SpawnDev.BlazorJS](https://github.com/LostBeard/SpawnDev.BlazorJS) and [SpawnDev.BlazorJS.WebWorkers](https://github.com/LostBeard/SpawnDev.BlazorJS.WebWorkers)
## Quick Start
A very basic and verbose example. Create a new .Net 8 Blazor WebAssembly Standalone App project. `Progressive Web Application` is optional, but not needed for this example.### Add Nuget
Add Nuget SpawnDev.BlazorJS.WebWorkers to the project.
[![NuGet](https://img.shields.io/nuget/dt/SpawnDev.BlazorJS.WebWorkers.svg?label=SpawnDev.BlazorJS.WebWorkers)](https://www.nuget.org/packages/SpawnDev.BlazorJS.WebWorkers)### wwwroot/index.html
If your project is a PWA, remove the ServiceWorker registration from `index.html`. SpawnDev.BlazorJS.WebWorkers will register the service worker on its own when called in the `Program.cs`.
Delete below line (if found) in `index.html`:
`navigator.serviceWorker.register('service-worker.js');`### Program.cs
A minimal Program.cs
```cs
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add("#app");
builder.RootComponents.Add("head::after");
// SpawnDev.BlazorJS
builder.Services.AddBlazorJSRuntime();
// SpawnDev.BlazorJS.WebWorkers
builder.Services.AddWebWorkerService();
// Register a ServiceWorker handler (AppServiceWorker here) that inherits from ServiceWorkerEventHandler
builder.Services.RegisterServiceWorker();
// Or Unregister the ServiceWorker if no longer desired
//builder.Services.UnregisterServiceWorker();
// SpawnDev.BlazorJS startup (replaces RunAsync())
await builder.Build().BlazorJSRunAsync();
```### AppServiceWorker.cs
A verbose service worker implementation.
- Handle ServiceWorker events by overriding the ServiceWorkerEventHandler base class virtual methods.
- The ServiceWorker event handlers are only called when running in a ServiceWorkerGlobalScope context.
- The AppServiceWorker singleton may be started in any scope and therefore must be scope aware. (For example, do not try to use localStorage in a Worker scope.)```cs
public class AppServiceWorker : ServiceWorkerEventHandler
{
public AppServiceWorker(BlazorJSRuntime js) : base(js)
{}
// called before any ServiceWorker events are handled
protected override async Task OnInitializedAsync()
{
// This service may start in any scope. This will be called before the app runs.
// If JS.IsWindow == true be careful not stall here.
// you can do initialization based on the scope that is running
Log("GlobalThisTypeName", JS.GlobalThisTypeName);
}protected override async Task ServiceWorker_OnInstallAsync(ExtendableEvent e)
{
Log($"ServiceWorker_OnInstallAsync");
_ = ServiceWorkerThis!.SkipWaiting(); // returned task can be ignored
}protected override async Task ServiceWorker_OnActivateAsync(ExtendableEvent e)
{
Log($"ServiceWorker_OnActivateAsync");
await ServiceWorkerThis!.Clients.Claim();
}protected override async Task ServiceWorker_OnFetchAsync(FetchEvent e)
{
Log($"ServiceWorker_OnFetchAsync", e.Request.Method, e.Request.Url);
Response ret;
try
{
ret = await JS.Fetch(e.Request);
}
catch (Exception ex)
{
ret = new Response(ex.Message, new ResponseOptions { Status = 500, StatusText = ex.Message, Headers = new Dictionary { { "Content-Type", "text/plain" } } });
Log($"ServiceWorker_OnFetchAsync failed: {ex.Message}");
}
return ret;
}protected override async Task ServiceWorker_OnMessageAsync(ExtendableMessageEvent e)
{
Log($"ServiceWorker_OnMessageAsync");
}protected override async Task ServiceWorker_OnPushAsync(PushEvent e)
{
Log($"ServiceWorker_OnPushAsync");
}protected override void ServiceWorker_OnPushSubscriptionChange(Event e)
{
Log($"ServiceWorker_OnPushSubscriptionChange");
}protected override async Task ServiceWorker_OnSyncAsync(SyncEvent e)
{
Log($"ServiceWorker_OnSyncAsync");
}protected override async Task ServiceWorker_OnNotificationCloseAsync(NotificationEvent e)
{
Log($"ServiceWorker_OnNotificationCloseAsync");
}protected override async Task ServiceWorker_OnNotificationClickAsync(NotificationEvent e)
{
Log($"ServiceWorker_OnNotificationClickAsync");
}
}
```