Skip to content

Commit c8d9c87

Browse files
committed
Version 3.2.2
1 parent ef2aa4a commit c8d9c87

8 files changed

Lines changed: 160 additions & 6 deletions

File tree

SpawnDev.BlazorJS.WebWorkers.Demo/Pages/Counter.razor

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,72 @@
11
@page "/counter"
2+
@using SpawnDev.BlazorJS.JSObjects
23
@implements IDisposable
34

5+
46
<PageTitle>Counter</PageTitle>
57

68
<h1>Window Shared Counter</h1>
79
<p>
8-
Open this page in another window. You will see that the new window will have the same counter value as this window.
9-
Clicking the button on either window will increment the counter on all windows.
10+
Open this page in another window. You will see that the new window will have the same counter value as this window.
11+
Clicking the button on either window will increment the counter on all windows.
1012
</p>
1113
<p>
12-
This demonstrates calling a static method in another window inside a component.<br/>
14+
This demonstrates calling a static method in another window inside a component.<br />
1315
</p>
1416

1517
<p role="status">Current count: @currentCount</p>
1618

19+
<p>
20+
<div>Instance count: @(WebWorkerService.Instances.Count)</div>
21+
@foreach (var instance in WebWorkerService.Instances)
22+
{
23+
var thisInstance = WebWorkerService.InstanceId == instance.Info.InstanceId;
24+
var name = string.IsNullOrEmpty(instance.Info.Name) ? "[UNNAMED]" : instance.Info.Name;
25+
var scope = instance.Info.Scope.ToString();
26+
if (instance.Info.IFrameWorker) scope += " IFrame";
27+
if (thisInstance) name += " (THIS)";
28+
<div style="padding: 5px;">
29+
<div>Name: @name</div>
30+
<div>Scope: @scope</div>
31+
<div>InstanceId: @instance.Info.InstanceId</div>
32+
<div>ParentId: @instance.Info.ParentInstanceId</div>
33+
<div>OwnerId: @instance.Info.OwnerId</div>
34+
<div><button class="btn btn-primary" @onclick="@(() => CloseIt(instance))">❌</button></div>
35+
</div>
36+
}
37+
</p>
38+
1739
<button class="btn btn-primary" @onclick="IncrementCount">Increment Count</button>
1840

1941
<button class="btn btn-primary" @onclick="OpenNewWindow">Open New Window</button>
42+
<button class="btn btn-primary" @onclick="OpenNewIFrameWorker">New IFrame Worker</button>
43+
<button class="btn btn-primary" @onclick="OpenNewWebWorker">New WebWorker</button>
44+
<button class="btn btn-primary" @onclick="OpenNewSharedWorker">New SharedWebWorker</button>
2045

2146
@code {
2247
[Inject]
2348
WebWorkerService WebWorkerService { get; set; } = default!;
2449

50+
static void CloseThis()
51+
{
52+
var JS = BlazorJSRuntime.JS;
53+
JS.Log("Closing...");
54+
Toolbox.Async.Run(async () =>
55+
{
56+
await Task.Delay(1000);
57+
using var frameElement = JS.Get<HTMLIFrameElement>("frameElement");
58+
if (frameElement != null)
59+
{
60+
frameElement.Remove();
61+
}
62+
try
63+
{
64+
JS.CallVoid("close");
65+
}
66+
catch { }
67+
});
68+
}
69+
2570
private int currentCount = 0;
2671
// holds the running instance of this component, if one
2772
static Counter? instance = null;
@@ -32,6 +77,52 @@
3277
var nmt = true;
3378
}
3479

80+
async Task CloseIt(AppInstance instance)
81+
{
82+
await instance.Run(() => CloseThis());
83+
}
84+
85+
async Task OpenNewIFrameWorker()
86+
{
87+
var instance = await WebWorkerService.GetIFrameWorker();
88+
var nmt = true;
89+
}
90+
91+
async Task OpenNewWebWorker()
92+
{
93+
var instance = await WebWorkerService.GetWebWorker();
94+
var nmt = true;
95+
}
96+
97+
async Task OpenNewSharedWorker()
98+
{
99+
var name = $"SHARED_{DateTime.Now.ToString("s")}";
100+
var instance = await WebWorkerService.GetSharedWebWorker(name);
101+
var nmt = true;
102+
}
103+
104+
protected override void OnInitialized()
105+
{
106+
WebWorkerService.OnInstanceFound += WebWorkerService_OnInstanceFound;
107+
WebWorkerService.OnInstanceLost += WebWorkerService_OnInstanceLost;
108+
WebWorkerService.OnInstancesChanged += WebWorkerService_OnInstancesChanged;
109+
}
110+
111+
void WebWorkerService_OnInstancesChanged()
112+
{
113+
114+
}
115+
116+
void WebWorkerService_OnInstanceFound(AppInstance instance)
117+
{
118+
StateHasChanged();
119+
}
120+
121+
void WebWorkerService_OnInstanceLost(AppInstance instance)
122+
{
123+
StateHasChanged();
124+
}
125+
35126
// this static method can be called by other running instances
36127
static void SetInstanceCount(int count)
37128
{
@@ -71,6 +162,9 @@
71162
{
72163
// unset this instance on the static var
73164
instance = null;
165+
WebWorkerService.OnInstanceFound -= WebWorkerService_OnInstanceFound;
166+
WebWorkerService.OnInstanceLost -= WebWorkerService_OnInstanceLost;
167+
WebWorkerService.OnInstancesChanged -= WebWorkerService_OnInstancesChanged;
74168
}
75169
private async Task IncrementCount()
76170
{

SpawnDev.BlazorJS.WebWorkers.Demo/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
// add service(s) that holds unit tests
2929
builder.Services.AddSingleton<UnitTestsService>();
30+
//builder.Services.AddSingleton<IFrameUnitTestsService>();
3031

3132
// add root elements if running in the window
3233
if (JS.IsWindow)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using SpawnDev.Blazor.UnitTesting;
2+
3+
namespace SpawnDev.BlazorJS.WebWorkers.Demo.Services
4+
{
5+
public class IFrameUnitTestsService(BlazorJSRuntime JS, WebWorkerService WebWorkerService, IMathsService MathService, AsyncCallDispatcherTest CallDispatcherBaseTestClass)
6+
{
7+
8+
9+
[TestMethod]
10+
public async Task WebWorkerAppSettingsReadTest()
11+
{
12+
if (!WebWorkerService.WebWorkerSupported)
13+
{
14+
throw new UnsupportedTestException("Worker not supported by browser.");
15+
}
16+
// test key to read from appsettings.json
17+
var testKey = "Message";
18+
// get value loaded in this context to compare to worker returned value
19+
var testValueWindow = await MathService.ReadAppSettingsValue(testKey);
20+
// get worker and read the value from that context
21+
var worker = await WebWorkerService.GetIFrameWorker();
22+
var mathService = worker!.GetService<IMathsService>();
23+
var testValueWorker = await mathService.ReadAppSettingsValue(testKey);
24+
// compare
25+
if (testValueWorker != testValueWindow) throw new Exception("Unexpected result");
26+
Console.WriteLine($"WebWorkerAppSettingsReadTest value: {testValueWorker}");
27+
}
28+
}
29+
}

SpawnDev.BlazorJS.WebWorkers.Demo/SpawnDev.BlazorJS.WebWorkers.Demo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<CompressionEnabled>false</CompressionEnabled>
8+
<LangVersion>latest</LangVersion>
89
</PropertyGroup>
910

1011
<ItemGroup>

SpawnDev.BlazorJS.WebWorkers/AppInstanceInfo.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,12 @@ public class AppInstanceInfo
5353
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
5454
public string? LockName { get; set; }
5555
/// <summary>
56-
/// Returns true if this instance is a TaaskPool worker
56+
/// Returns true if this instance is a TaskPool worker
5757
/// </summary>
5858
public bool TaskPoolWorker { get; set; }
59+
/// <summary>
60+
/// Returns true if this instance is an IFrame worker
61+
/// </summary>
62+
public bool IFrameWorker { get; set; }
5963
}
6064
}

SpawnDev.BlazorJS.WebWorkers/SpawnDev.BlazorJS.WebWorkers.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
7-
<Version>3.2.1</Version>
7+
<Version>3.2.2</Version>
88
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
99
<GenerateDocumentationFile>true</GenerateDocumentationFile>
1010
<EmbedAllSources>true</EmbedAllSources>
@@ -22,6 +22,7 @@
2222
<NoPackageAnalysis>true</NoPackageAnalysis>
2323
<EnableDefaultCompileItems>true</EnableDefaultCompileItems>
2424
<IsPackable>true</IsPackable>
25+
<LangVersion>latest</LangVersion>
2526
</PropertyGroup>
2627

2728
<ItemGroup>
@@ -76,7 +77,7 @@
7677
</PropertyGroup>
7778

7879
<ItemGroup>
79-
<PackageReference Include="SpawnDev.BlazorJS" Version="3.5.0" />
80+
<PackageReference Include="SpawnDev.BlazorJS" Version="3.5.9" />
8081
</ItemGroup>
8182

8283
<ItemGroup>

SpawnDev.BlazorJS.WebWorkers/WebWorker.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace SpawnDev.BlazorJS.WebWorkers
44
{
5+
/// <summary>
6+
/// WebWorker
7+
/// </summary>
58
public class WebWorker : ServiceCallDispatcher, IDisposable
69
{
710
public static bool Supported;

SpawnDev.BlazorJS.WebWorkers/WebWorkerService.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ public WebWorkerService(IBackgroundServiceManager webAssemblyServices, BlazorJSR
190190
var isTaskPoolWorker = queryParams["taskPool"] == "1" && JS.IsScope(GlobalScope.DedicatedAndSharedWorkers);
191191
var instanceOwnerId = queryParams[instanceOwnerIdKey];
192192
var instanceChildId = queryParams[childIdKey];
193+
193194
if (!string.IsNullOrEmpty(instanceOwnerId) && !string.IsNullOrEmpty(instanceChildId))
194195
{
195196
queryParams.Remove(childIdKey);
@@ -207,6 +208,7 @@ public WebWorkerService(IBackgroundServiceManager webAssemblyServices, BlazorJSR
207208
}
208209
Info = new AppInstanceInfo
209210
{
211+
ParentInstanceId = instanceOwnerId,
210212
OwnerId = instanceOwnerId,
211213
ChildId = instanceChildId,
212214
InstanceId = InstanceId,
@@ -216,6 +218,14 @@ public WebWorkerService(IBackgroundServiceManager webAssemblyServices, BlazorJSR
216218
Url = locationHref,
217219
TaskPoolWorker = isTaskPoolWorker,
218220
};
221+
if (js.IsWindow)
222+
{
223+
using var frameElement = JS.Get<HTMLIFrameElement>("frameElement");
224+
if (frameElement != null)
225+
{
226+
Info.IFrameWorker = !string.IsNullOrWhiteSpace(instanceOwnerId);
227+
}
228+
}
219229
BroadcastChannelSupported = !JS.IsUndefined(nameof(BroadcastChannel));
220230
if (BroadcastChannelSupported)
221231
{
@@ -630,6 +640,8 @@ private async Task InitAsync()
630640
// this window is owned by another instance
631641
// todo I guess nothing really, it knows when this winow is started and is ready
632642
// could load Info.Url if it is set
643+
644+
JS.Log($"--- window", Info);
633645
}
634646
}
635647
else if (JS.GlobalThis is DedicatedWorkerGlobalScope workerGlobalScope)
@@ -982,6 +994,9 @@ public async Task<bool> UnregisterServiceWorker()
982994
{
983995
webWorkerOptions.QueryParams["indexHtml"] = WorkerIndexHtml;
984996
}
997+
var childId = Guid.NewGuid().ToString();
998+
webWorkerOptions.QueryParams[instanceOwnerIdKey] = InstanceId;
999+
webWorkerOptions.QueryParams[childId] = childId;
9851000
if (string.IsNullOrEmpty(webWorkerOptions.ScriptUrl))
9861001
{
9871002
webWorkerOptions.ScriptUrl = webWorkerOptions.WorkerOptions.Type == "module" ? WebWorkerModuleJSScript : WebWorkerJSScript;
@@ -1012,6 +1027,9 @@ public async Task<bool> UnregisterServiceWorker()
10121027
{
10131028
queryParams["indexHtml"] = WorkerIndexHtml;
10141029
}
1030+
var childId = Guid.NewGuid().ToString();
1031+
queryParams[instanceOwnerIdKey] = InstanceId;
1032+
queryParams[childId] = childId;
10151033
var scriptUrl = WebWorkerJSScript;
10161034
if (queryParams.Count > 0)
10171035
{
@@ -1039,6 +1057,9 @@ public async Task<bool> UnregisterServiceWorker()
10391057
{
10401058
queryParams["indexHtml"] = WorkerIndexHtml;
10411059
}
1060+
var childId = Guid.NewGuid().ToString();
1061+
queryParams[instanceOwnerIdKey] = InstanceId;
1062+
queryParams[childId] = childId;
10421063
var scriptUrl = WebWorkerJSScript;
10431064
if (queryParams.Count > 0)
10441065
{

0 commit comments

Comments
 (0)