介绍
我必须找到一种解决方案来解决旧的 Windows 窗体应用程序和基于 Web 的 Blazor 应用程序之间的通信问题。
您可能想知道,为什么 Windows 窗体应该与 Blazor 通信?场景是:我有一个旧的 Framework 2.0 应用程序,然后它迁移到 Framework 4.8,安装在使用 Windows API 但需要与 Blazor 应用程序交换数据的客户端上。
背景
ASP.NET Core SignalR在 Blazor App 中实现非常简单,并且通信非常迅速。我建议您阅读 Microsoft 教程以了解这些功能。
Blazor 代码
注意:下面,我有相同的微软教程步骤,如果你已经制作了教程,你可以使用它。
首先,我们需要 Visual Studio 2022 并创建一个 Blazor 服务器应用程序 .NET 6.0。在应用程序中,创建一个名为Hubs
的文件夹,然后创建一个名为ChatHub
.
using Microsoft.AspNetCore.SignalR; using System.Threading.Tasks; namespace RadzenBlazorSignalR.Hubs { public class ChatHub : Hub //NB: inherits from Hub { public async Task SendMessage(string message) { await Clients.All.SendAsync("ReceiveMessage", message); } } }
在Program.cs中,映射 Blazor 中心的终结点:
app.UseEndpoints(endpoints => { endpoints.MapHub<ChatHub>("/chathub"); });
现在 Hub 已经准备好了,但是应用程序需要发送和接收一些消息,所以我们需要实现客户端。
为此,首先添加Microsoft.AspNetCore.SignalR.Client
包,然后创建一个方法来初始化连接。
HubConnection hubConnection; string _messageRecived { get; set; } protected override async Task OnInitializedAsync() { hubConnection = new HubConnectionBuilder() .WithUrl(MyUriHelper.ToAbsoluteUri("/chathub")) .Build(); hubConnection.On<string>("ReceiveMessage", (message) => { _messageRecived = message; StateHasChanged(); }); await hubConnection.StartAsync(); }
在上面的代码中,我使用了OnInitializedAsync()
在 Blazor 页面启动时触发的 Blazor 后端代码。
HubConnectionBuilder()
ToAbsoluteUri()
从和 Hub 的 name构建本地 Blazor 应用程序 Uri chathub
。
hubConnection.On<>
映射ReceiveMessage
事件,在调用方法时触发SendMessage()
。
现在准备一个发送消息的方法,您可以从 Blazor 页面按钮调用该方法。
public async Task Send() { if (hubConnection is not null) { await hubConnection.SendAsync("SendMessage", _messageToSend); } }
在完整的 Blazor 页面后端代码下方。
public partial class HomeComponent { [Inject] protected NavigationManager MyUriHelper { get; set; }//to get current Uri public string _messageToSend { get; set; }//to bind on textbox public string _messageRecived { get; set; }//to bind on a label or so... private HubConnection hubConnection; protected override async Task OnInitializedAsync() { hubConnection = new HubConnectionBuilder() .WithUrl(MyUriHelper.ToAbsoluteUri("/chathub")) .Build(); //receive event hubConnection.On<string>("ReceiveMessage", (message) => { _messageRecived = message; StateHasChanged(); }); await hubConnection.StartAsync(); } //send message //call Send method from button click public async Task Send() { if (hubConnection is not null) { await hubConnection.SendAsync("SendMessage", _messageToSend); } } }
@page "/" @page "/home" @layout MainLayout @inherits RadzenBlazorSignalR.Pages.HomeComponent @using Radzen @using Radzen.Blazor <PageTitle>Home</PageTitle> <RadzenContent Container="main"> <ChildContent> <RadzenHeading Size="H1" Text="Home"> </RadzenHeading> <div class="row"> <div class="col-md-3"> <RadzenTextBox @bind-Value="@(_messageToSend)" Name="Textbox0"> </RadzenTextBox> </div> <div class="col-md-3"> <RadzenButton Text="Invia" Click="@Button0Click"> </RadzenButton> </div> <div class="col-md-4"> <RadzenLabel Text="@($"{(_messageRecived)}")"> </RadzenLabel> </div> </div> </ChildContent> </RadzenContent>
注意:我在 Razor 页面中使用了 Radzen 组件。如果您有兴趣,请看这里。
现在测试应用程序,当应用程序启动时,将 url 复制到另一个浏览器中,如果一切正常,当您从应用程序发送消息时,您会在另一个浏览器上看到,反之亦然。
Windows 窗体代码
现在我们构建了一个 Windows 窗体应用程序,客户端使用它来发送和接收来自本地 Blazor 应用程序的消息。
打开 Visual Studio 并创建一个新的 Windows 窗体框架 4.8 应用程序。
从 NuGet 安装Microsoft.AspNetCore.SignalR.Client
包含 ASP.NET Core SignalR 客户端的包。
我们需要执行相同的 Blazor 客户端实现,因此创建初始化方法并从加载表单中调用它。
async Task InizializzaConnectioTuBlazorHub() { hubConnection = new HubConnectionBuilder() .WithUrl("http://localhost:5000/chathub") .Build(); hubConnection.On<string>("ReceiveMessage", (message) => { _messageRecived = message; textBox1.Text= _messageRecived; }); await hubConnection.StartAsync(); }
注意本地应用程序 URL“http://localhost:5000/chathub”。
准备Send
方法并从单击按钮事件中调用它。
async Task InviaAsync() { if (hubConnection != null) { await hubConnection.SendAsync("SendMessage", "Desktop: Ciao"); } }
下面是完整的代码:
private void Form1_Load(object sender, EventArgs e) { InizializzaConnectioTuBlazorHub(); } private void button1_Click(object sender, EventArgs e) { Send(); } HubConnection hubConnection; string _messageRecived; async Task InizializzaConnectioTuBlazorHub() { hubConnection = new HubConnectionBuilder() .WithUrl("http://localhost:5000/chathub") .Build(); hubConnection.On<string>("ReceiveMessage", (message) => { _messageRecived = message; textBox1.Text= _messageRecived; }); await hubConnection.StartAsync(); } async Task Send() { if (hubConnection != null) { await hubConnection.SendAsync("SendMessage", "Desktop: Bye!"); } }
就这样!
如果启动 Blazor 应用和 Windows 应用,则可以从所有应用发送和接收消息。
结论
在此示例中,我们看到了与 SignalR 进行通信是多么容易,不仅在 Blazor 应用程序之间,而且在 Windows 桌面应用程序之间。