Maui学习笔记-SignalR简单介绍
SignalR是ASP.NET Core中的一个库,支持服务器与其连接的客服端之间的双象通信,它允许服务器立即将更新的消息推送到客服端,而不是要求客户端轮询服务器来获取更新
创建项目
使用SignalR在服务器实时发送消息给客服端,客服端拿到消息后在UI页面更新
首先创建一个Web API项目
添加一个BidsHub类继承自Hub
public class BidsHub:Hub
{
public static bool IsAuctionRunning = true;
public void AcceptBig(string winner)
{
IsAuctionRunning = false;
}
}
-
注册SignalR服务,并设置API接口
注册服务
builder.Services.AddSignalR();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseHttpsRedirection();
//
app.MapHub<BidsHub>("/auction");
//获取服务
using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
var hubContext = services.GetRequiredService<IHubContext<BidsHub>>();
//启动任务
_ = Task.Run(async () =>
{
Random random = new Random();
int price = 1;
//循坏出价价格
while (BidsHub.IsAuctionRunning)
{
price = random.Next(price, price + 100);
await hubContext.Clients.All.SendAsync("BidReceived", new
{
Bidder = $"Company{random.Next(1, 10)}",
Price = price
});
//随机延迟一个发送消息的时间
await Task.Delay(random.Next(500, 5000));
}
});
}
app.Run();
创建Maui项目
首先需要安装NuGet包
-
Microsoft.AspNetCore.SignalR.Client
-
CommunityToolkit.Mvvm
-
CommunityToolkit.Maui(需要在program.cs中引入)
-
创建一个类来接收服务器的数据
public class BidData(string bidder, decimal price)
{
public string Bidder { get; set; } = bidder;
public decimal Price { get; set; } = price;
}
-
创建ViewModel
[ObservableObject]
public partial class MainViewModel
{
//引入SignalR Hub连接对象
HubConnection _hubConnection;
private bool isBidAccepted;
[ObservableProperty] private ObservableCollection<BidData> _bids = new();
//连接服务器
[RelayCommand]
async Task Initialize()
{
_hubConnection = new HubConnectionBuilder()
.WithUrl("你的IP地址/auction")
.Build();
_hubConnection.On<BidData>("BidReceived", bid =>
{
Bids.Insert(0, bid);
});
await _hubConnection.StartAsync();
}
//接受出价命令
[RelayCommand(CanExecute = nameof(CanAcceptBid))]
async Task AcceptBid(BidData bid)
{
await _hubConnection.InvokeCoreAsync("AcceptBid", args:[bid.Bidder]);
isBidAccepted = true;
}
bool CanAcceptBid()=> !isBidAccepted;
}
-
MainPage
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm = "clr-namespace:SignalRMaui.ViewModels"
xmlns:model="clr-namespace:SignalRMaui.Models"
xmlns:tk="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
x:Class="SignalRMaui.MainPage">
<ContentPage.Behaviors>
<tk:EventToCommandBehavior EventName="Appearing" Command="{Binding InitializeCommand}"/>
</ContentPage.Behaviors>
<ContentPage.BindingContext>
<vm:MainViewModel/>
</ContentPage.BindingContext>
<ContentPage.Resources>
<DataTemplate
x:Key="bidTemplate"
x:DataType="model:BidData">
<Grid ColumnDefinitions="*,100"
RowDefinitions="30,26"
Padding="1,18">
<Label
Text="{Binding Price,StringFormat='{0:C0}'}"
TextColor="LawnGreen"
FontSize="20"/>
<Label
Text="{Binding Bidder}"
Grid.Row="1"/>
<Button Text="接受"
Command="{Binding Path=BindingContext.AcceptBidCommand,Source={RelativeSource Mode=FindAncestor,AncestorType={x:Type CollectionView}}}"
CommandParameter="{Binding}"
HeightRequest="40"
Grid.Column="1"
Grid.RowSpan="2"/>
</Grid>
</DataTemplate>
</ContentPage.Resources>
<CollectionView
ItemsSource="{Binding Bids}"
ItemTemplate="{StaticResource bidTemplate}"></CollectionView>
</ContentPage>