Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multithreading in Blazor wasm

I'm developing simple online game using Blazor WASM. Just recently I found that Blazor client is single threaded, which is quite disastrous for most of my algorithms. I want to implement better architecture that authoritative server and enable to run the code on client side as well (for lag compensation and stuff...). The idea of online communication for each frame is as follows:

  1. When client is connected, it receives all information about the state of the game (not problematic)
  2. When client do some action (move, shoot...) it sends information to server about the action
  3. Server each frame collects all received actions and sends it to all clients
  4. Clients proceed all actions that server sent them.
  5. Client and server proceed all game algorithms for each frame

So on client side there are basically three threads - one for sending actions to server when key is pressed, second for receiving messages from server and third for executing the game code. As you can see, one thread is not enough for me :D

Additional info - online communication is realized by SignalR.

I know that multithreading will be possible in .net 8 (but sadly I can't wait). I tried prerelease but I didn't get it running.

Any help or tips greatly appreciated ;)

Providing code for better understanding.

//Executed 60 per second
private async Task Frame()
{
    //serialization of actions
    json = JsonConvert.SerializeObject(myActions);
    Task.Run(() => hubConnection.SendAsync("ExecuteList", json, id)); //still 
    the same thread
    myActions.Clear();
    ToolsGame.ProceedFrame(gvars, now);
    StateHasChanged();  
}

SignalR listening for messages from server:

hubConnection.On<string>("ExecuteList", (actionMethodNamesJson) =>
{
        ExecuteList(actionMethodNamesJson); //deserialize actions from all clients
        StateHasChanged();
});
like image 756
Nys Avatar asked Oct 27 '25 03:10

Nys


1 Answers

SpawnDev.BlazorJS.WebWorkers adds multithreading via Workers and SharedWorkers to Blazor WASM .Net 6, 7 and 8. Just add the Nuget package, modify your Program.cs and then you can call any registered service interface on a Worker or SharedWorker thread.

// Program.cs
// ...
using SpawnDev.BlazorJS;
using SpawnDev.BlazorJS.WebWorkers;
    
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

// Add SpawnDev.BlazorJS.BlazorJSRuntime
builder.Services.AddBlazorJSRuntime();

// Add SpawnDev.BlazorJS.WebWorkers.WebWorkerService
builder.Services.AddWebWorkerService();

// Add services that will be called on the main thread and/or worker threads (Worker services must use interfaces)
builder.Services.AddSingleton<IMathsService, MathsService>();

// build and Init using BlazorJSRunAsync (instead of RunAsync)
await builder.Build().BlazorJSRunAsync();

To use it:

[Inject]
WebWorkerService workerService { get; set; }

// Get a new WebWorker
var webWorker = await workerService.GetWebWorker();

// Get WebWorker service proxy
var workerMathService = webWorker.GetService<IMathsService>();

// Call async methods on your worker service thread
var result = await workerMathService.CalculatePi(piDecimalPlaces);

Documentation and examples are on GitHub. I am quick to help with any problems, just file an issue on the repo.

GitHub repo: https://github.com/LostBeard/SpawnDev.BlazorJS

Nuget page: https://www.nuget.org/packages/SpawnDev.BlazorJS.WebWorkers

like image 149
LoneSpawn Avatar answered Oct 30 '25 18:10

LoneSpawn