Skip to content

Commit

Permalink
Examples for calling static dotnet from worker, and fixes bug for cal…
Browse files Browse the repository at this point in the history
…ling instance methods (#106)

* dotnet8 fixes and some examples

* Fix copy-paste error

* version up JsRuntime
  • Loading branch information
Tewr authored Mar 12, 2024
1 parent 72dc8e7 commit fce9ea2
Show file tree
Hide file tree
Showing 23 changed files with 340 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

<ItemGroup>
<ProjectReference Include="..\..\..\SharedPages\BlazorWorker.Demo.SharedPages.csproj" />
<ProjectReference Include="..\..\..\Shared\BlazorWorker.Demo.Shared.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/ComplexSerialization"
<BlazorWorker.Demo.SharedPages.Pages.ComplexSerialization />
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/IndexedDb"
<BlazorWorker.Demo.SharedPages.Pages.IndexedDb />
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/JsDirect"
<BlazorWorker.Demo.SharedPages.Pages.JsDirect />
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/JsInteractions"
<BlazorWorker.Demo.SharedPages.Pages.JsInteractions />
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using BlazorWorker.Core;
using BlazorWorker.Demo.Client;
//using BlazorWorker.Demo.IoCExample;
using BlazorWorker.Demo.Shared;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

Expand All @@ -9,7 +8,6 @@
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddWorkerFactory();
//builder.Services.AddIndexedDbDemoPersonConfig();
builder.Services.AddDemoDependencies();

await builder.Build().RunAsync();
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<body>
<div id="app">
<div style="margin: 100px auto; width: 500px; height: 120px; text-align: center; ">
<img src="loading-icon.svg" width="97" height="88" />
<img src="loading-icon.svg" width="97" height="88" />
</div>
<svg class="loading-progress">
<circle r="40%" cx="50%" cy="50%" />
Expand All @@ -31,6 +31,7 @@
</div>
<script src="_framework/blazor.webassembly.js"></script>
<script src="_content/TG.Blazor.IndexedDB/indexedDb.Blazor.js"></script>
<script src="_content/BlazorWorker.Demo.SharedPages/JsDirectExample.js"></script>
</body>

</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@page "/JsInteractions"
<BlazorWorker.Demo.SharedPages.Pages.JsInteractions />
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using BlazorWorker.Core;
using BlazorWorker.Demo.Client;
using BlazorWorker.Demo.IoCExample;
using BlazorWorker.Demo.Shared;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
Expand All @@ -10,9 +8,6 @@
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddWorkerFactory();
builder.Services.AddIndexedDbDemoPersonConfig();

builder.Services.AddTransient<JsDirectExample>();
builder.Services.AddDemoDependencies();

await builder.Build().RunAsync();
4 changes: 3 additions & 1 deletion src/BlazorWorker.Demo/Shared/BlazorWorker.Demo.Shared.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
Expand All @@ -11,6 +11,8 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\BlazorWorker.Demo.IoCExample\BlazorWorker.Demo.IoCExample.csproj" />
<ProjectReference Include="..\..\BlazorWorker.Extensions.JSRuntime\BlazorWorker.Extensions.JSRuntime.csproj" />
<ProjectReference Include="..\..\BlazorWorker.ServiceFactory\BlazorWorker.BackgroundServiceFactory.csproj" />
<ProjectReference Include="..\..\BlazorWorker.WorkerBackgroundService\BlazorWorker.WorkerBackgroundService.csproj" />
<ProjectReference Include="..\..\BlazorWorker.WorkerCore\BlazorWorker.WorkerCore.csproj" />
Expand Down
9 changes: 4 additions & 5 deletions src/BlazorWorker.Demo/Shared/JsDirectExample.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
using BlazorWorker.Core;
using BlazorWorker.BackgroundServiceFactory;
using BlazorWorker.Core;
using BlazorWorker.WorkerBackgroundService;
using BlazorWorker.WorkerCore;
using Microsoft.JSInterop;
using System;
using System.Threading.Tasks;
using BlazorWorker.BackgroundServiceFactory;
using Microsoft.JSInterop;
using BlazorWorker.WorkerBackgroundService;
using System.Runtime.InteropServices.JavaScript;

namespace BlazorWorker.Demo.Shared
{
Expand Down
129 changes: 129 additions & 0 deletions src/BlazorWorker.Demo/Shared/JsInteractionsExample.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
using BlazorWorker.BackgroundServiceFactory;
using BlazorWorker.Core;
using BlazorWorker.Extensions.JSRuntime;
using BlazorWorker.WorkerBackgroundService;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
using System;
using System.Runtime.InteropServices.JavaScript;
using System.Threading.Tasks;

namespace BlazorWorker.Demo.Shared
{
public partial class JsInteractionsExample
{
private readonly IWorkerFactory workerFactory;
private IWorkerBackgroundService<JsInteractionsExampleWorkerService> service;
public event EventHandler<string> LogHandler;
public event EventHandler<string> WorkerLogHandler;

public JsInteractionsExample(IWorkerFactory workerFactory)
{
this.workerFactory = workerFactory;
}

private void Log(string message)
{
LogHandler?.Invoke(this, message);
}

private void WorkerLog(string message)
{
WorkerLogHandler?.Invoke(this, message);
}

public async Task Execute()
{
if (this.service == null)
{
Log("Execute: Creating worker...");
var worker = await this.workerFactory.CreateAsync();
Log("Execute: Creating service...");
this.service = await worker
.CreateBackgroundServiceUsingFactoryAsync<JsInteractionsExampleStartup, JsInteractionsExampleWorkerService>(x =>
x.Resolve<JsInteractionsExampleWorkerService>());
Log("Execute: Registering log event...");
await this.service.RegisterEventListenerAsync<string>("Log", (s, log) => WorkerLog(log));
Log("Execute: Service Created.");
}

Log($"Execute: Calling ExecuteJsInteractionWithCallback on worker...");
await service.RunAsync(s => s.ExecuteJsInteractionWithCallback());
Log("Execute: Done");
}

}

#region Runs on web worker
public class JsInteractionsExampleStartup
{
private readonly IServiceProvider serviceProvider;

public JsInteractionsExampleStartup()
{
var serviceCollection = new ServiceCollection();
Configure(serviceCollection);
this.serviceProvider = serviceCollection.BuildServiceProvider();
}

public T Resolve<T>() => serviceProvider.GetService<T>();

public void Configure(IServiceCollection services)
{
services.AddBlazorWorkerJsRuntime()
.AddTransient<JsInteractionsExampleWorkerService>();
}

}

public partial class JsInteractionsExampleWorkerService : IDisposable, IAsyncDisposable
{
private readonly IJSRuntime blazorJsRuntime;

public event EventHandler<string> Log;

private DotNetObjectReference<JsInteractionsExampleWorkerService> selfRef;

public JsInteractionsExampleWorkerService(IJSRuntime blazorJsRuntime)
{
this.blazorJsRuntime = blazorJsRuntime;
}
public async Task ExecuteJsInteractionWithCallback()
{
// Method setupJsDirectForWorker is defined in BlazorWorker.Demo.SharedPages/wwwroot/JsDirectExample.js
await this.blazorJsRuntime.InvokeVoidAsync("importLocalScripts", "_content/BlazorWorker.Demo.SharedPages/JsInteractionsExample.js");

await this.blazorJsRuntime.InvokeVoidAsync("jsInteractionsExample", selfRef ??= DotNetObjectReference.Create(this));
}

/// <summary>
/// This instance method will be called from JsInteractionsExample.js.
/// </summary>
/// <param name="arg"></param>
[JSInvokable]
public void CallbackFromJavascript(string arg)
{
Console.WriteLine($"Worker Console: {nameof(CallbackFromJavascript)}('{arg}')");
Log?.Invoke(this, $"{nameof(CallbackFromJavascript)}('{arg}')");
}

[JSExport]
public static int StaticCallbackFromJs(string arg)
{
Console.WriteLine($"Worker Console: {nameof(StaticCallbackFromJs)}('{arg}')");
return 5;
}

public void Dispose()
{
selfRef?.Dispose();
}

public async ValueTask DisposeAsync()
{
this.Dispose();
}
}

#endregion
}
18 changes: 18 additions & 0 deletions src/BlazorWorker.Demo/Shared/SharedDemoExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using BlazorWorker.Core;
using BlazorWorker.Demo.IoCExample;
using Microsoft.Extensions.DependencyInjection;

namespace BlazorWorker.Demo.Shared
{
public static class SharedDemoExtensions
{
public static IServiceCollection AddDemoDependencies(this IServiceCollection serviceCollection)
{
serviceCollection.AddWorkerFactory();
serviceCollection.AddIndexedDbDemoPersonConfig();
serviceCollection.AddTransient<JsDirectExample>();
serviceCollection.AddTransient<JsInteractionsExample>();
return serviceCollection;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
<ProjectReference Include="..\..\BlazorWorker.WorkerCore\BlazorWorker.WorkerCore.csproj" />
<ProjectReference Include="..\Shared\BlazorWorker.Demo.Shared.csproj" />
</ItemGroup>

<ItemGroup>
<Content Update="Pages\JsInteractions.razor">
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>



Expand Down
11 changes: 0 additions & 11 deletions src/BlazorWorker.Demo/SharedPages/Pages/IndexedDb.razor
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,6 @@
var sw = new System.Diagnostics.Stopwatch();
IWorkerBackgroundService<MyIndexDBService> myIocIndexedDbService;


var serviceCollectionDependencies = new string[] {
"Microsoft.Extensions.DependencyInjection.Abstractions.dll"
#if NET5_0_OR_GREATER
,"System.Diagnostics.Tracing.dll"
#endif
#if NET6_0_OR_GREATER
,"Microsoft.Extensions.DependencyInjection.dll"
#endif
};

if (startupService == null)
{
output = $"{rn}{LogDate()} Creating background service Startup class...";
Expand Down
2 changes: 1 addition & 1 deletion src/BlazorWorker.Demo/SharedPages/Pages/JsDirect.razor
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
@inject JsDirectExample jsDirectExample

<script src="_content/BlazorWorker.Demo.SharedPages/JsDirectExample.js"></script>
<div class="row">
<div class="col-9 col-xs-12">
<script src="_content/BlazorWorker.Demo.SharedPages/JsDirectExample.js"></script>
<h1>JSDirect Calls</h1>

Demonstrates how to receive messages from a dotnet worker on the main/ui js thread directly.
Expand Down
82 changes: 82 additions & 0 deletions src/BlazorWorker.Demo/SharedPages/Pages/JsInteractions.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
@inject JsInteractionsExample jsDirectExample

<div class="row">
<div class="col-9 col-xs-12">
<h1>Interacting with Js Calls</h1>

Demonstrates how to call to js from a worker using IJsRuntime,
and how call back directly to a dotnet instance.


<br />
<br />
<button disabled=@RunDisabled @onclick=OnClick class="btn btn-primary">Run test</button><br /><br />
<br />
<br />
<div class="row">
<div class="col-6 col-xs-12">
<strong>JsInteractions.razor Output:</strong>

<hr />
<pre style="text-wrap: pretty">@output</pre>
</div>
<div class="col-6 col-xs-12">
<strong>Worker dotnet Output:</strong>
<hr />
<pre style="text-wrap: pretty">@workeroutput</pre>
</div>
</div>

</div>
<div class="col-3 col-xs-12">
<GithubSource RelativePath="Pages/JsDirect.razor" />
</div>
</div>
@code {
string output;
string workeroutput;
string RunDisabled => Running ? "disabled" : null;
bool Running = false;

protected override void OnInitialized()
{
jsDirectExample.LogHandler += (s, e) => log(e);
jsDirectExample.WorkerLogHandler += (s, e) => workerlog(e);
output = "";
workeroutput = "";
base.OnInitialized();
}

public async Task OnClick(EventArgs _)
{
Running = true;
try
{
await jsDirectExample.Execute();
}
catch (Exception e)
{
log($"Error = {e}");
}
finally
{
Running = false;
}
}

void log(string logStr){
output += $"{Environment.NewLine}{LogDate()} {logStr}";
StateHasChanged();
}

void workerlog(string logStr)
{
workeroutput += $"{Environment.NewLine}{LogDate()} {logStr}";
StateHasChanged();
}

private string LogDate()
{
return DateTime.Now.ToString("HH:mm:ss:fff");
}
}
3 changes: 3 additions & 0 deletions src/BlazorWorker.Demo/SharedPages/Shared/NavMenuLinksModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public class NavMenuLinksModel
{
new() { Icon = "document", Href="JsDirect", Text = "JsDirect" }
},
{
new() { Icon = "document", Href="JsInteractions", Text = "JsInteractions" }
},
{
new() { Icon = "fork", Href="https://github.com/tewr/BlazorWorker", Text = "To the source!" }
},
Expand Down
Loading

0 comments on commit fce9ea2

Please sign in to comment.