Blazor wasm 中的多线程

Nys*_*Nys 3 multithreading blazor blazor-webassembly

我正在使用 Blazor WASM 开发简单的在线游戏。最近我发现 Blazor 客户端是单线程的,这对于我的大多数算法来说都是灾难性的。我想实现比权威服务器更好的架构,并能够在客户端运行代码(用于滞后补偿等......)。各框架在线交流的思路如下:

  1. 当客户端连接时,它会收到有关游戏状态的所有信息(没有问题)
  2. 当客户端执行某些操作(移动、射击...)时,它会向服务器发送有关该操作的信息
  3. 服务器每帧收集所有收到的操作并将其发送给所有客户端
  4. 客户端执行服务器发送给他们的所有操作。
  5. 客户端和服务器对每一帧执行所有游戏算法

因此,在客户端,基本上有三个线程 - 第一个用于在按下按键时向服务器发送操作,第二个用于从服务器接收消息,第三个用于执行游戏代码。正如你所看到的,一个线程对我来说是不够的:D

附加信息 - 在线通信是通过 SignalR 实现的。

我知道 .net 8 中可以实现多线程(但遗憾的是我等不及了)。我尝试过预发布,但没有运行。

非常感谢任何帮助或提示;)

提供代码以便更好地理解。

//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();  
}
Run Code Online (Sandbox Code Playgroud)

SignalR 监听来自服务器的消息:

hubConnection.On<string>("ExecuteList", (actionMethodNamesJson) =>
{
        ExecuteList(actionMethodNamesJson); //deserialize actions from all clients
        StateHasChanged();
});
Run Code Online (Sandbox Code Playgroud)

Lon*_*awn 5

SpawnDev.BlazorJS.WebWorkers 通过 Workers 和 SharedWorkers 将多线程添加到 Blazor WASM .Net 6、7 和 8。只需添加 Nuget 包,修改 Program.cs,然后您就可以在 Worker 或 SharedWorker 线程上调用任何已注册的服务接口。

// 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();
Run Code Online (Sandbox Code Playgroud)

使用方法:

[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);
Run Code Online (Sandbox Code Playgroud)

文档和示例位于 GitHub 上。我很快就能帮助解决任何问题,只需在存储库上提出问题即可。

GitHub 仓库:https://github.com/LostBeard/SpawnDev.BlazorJS

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