SignalR消息推送

SignalR消息推送

不久前我看到一篇用asp.netcore调用SignalR做日志推送的博客,觉得蛮不错,就按照作者的教程实际攒了一套webapi,感觉确实挺好的,又查了一些关于SignalR的资料,做了一些完善,在这里进行汇总。

github链接

1. Signal概要

SignalR的实现机制与/.NET WCF或Remoting是相似的,都是使用远程代理来实现。它要实现的场景类似于实时的Web服务,实时web功能是让服务器代码将内容推送到连接的客户端立即可用,而不是让服务器等待客户端请求新数据的能力。这点儿类似于WebSocket。

2. 服务端代码
  • 使用asp.net core 新建一个WebApi的项目
  • nuget安装Microsoft.AspNetCore.SignalR类库
  • 在项目根目录新建Services目录,在其中添加两个类
  1. AlarmLogHub.cs
public class AlarmLogHub:Hub
{
}
  1. SignalRTimedHostedService.cs
public class SignalRTimedHostedService : IHostedService, IDisposable
{
private readonly IHubContext<AlarmLogHub> _hub;
private Timer _timer;

//模拟发送报警日志            
List<AlarmLogItem> lstLogs = new List<AlarmLogItem> {
new AlarmLogItem{ Type=AlarmLogType.Error,Text="OK WebSocket断连",Description="尝试连接50次,未成功重连!"},
new AlarmLogItem{ Type=AlarmLogType.Warn,Text="OK WebSocket断开重连",Description="尝试连接5次,成功重连!"},
new AlarmLogItem{ Type=AlarmLogType.Warn,Text="OK Restfull断连",Description="尝试连接30次,成功重连!"},
new AlarmLogItem{ Type=AlarmLogType.Error,Text="OK WebSocket断连",Description="第一次断开链接!"},
new AlarmLogItem{ Type=AlarmLogType.Info,Text="OK WebSocket连接成功",Description="首次成功连接!"},
new AlarmLogItem{ Type=AlarmLogType.Error,Text="OK WebSocket断连",Description="尝试连接第7次,未成功重连!"}
};

Random rd = new Random(DateTime.Now.Millisecond);
public SignalRTimedHostedService(IHubContext<AlarmLogHub> hub)
{
_hub = hub;
}
public Task StartAsync(CancellationToken cancellationToken)
{

_timer = new Timer(DoWork, null, TimeSpan.Zero,
	TimeSpan.FromSeconds(1));

return Task.CompletedTask;
}

private void DoWork(object state)
{
if (DateTime.Now.Second % rd.Next(1, 3) == 0)
{
	AlarmLogItem log = lstLogs[rd.Next(lstLogs.Count)];
	log.UpdateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
	_hub.Clients.All.SendAsync("ReceiveAlarmLog", log);
}
}
public Task StopAsync(CancellationToken cancellationToken)
{
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
public void Dispose()
{
_timer?.Dispose();
}
}
  1. 在启动设置文件Startup.cs注入服务
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddHostedService<SignalRTimedHostedService>();
services.AddSignalR(options => { options.EnableDetailedErrors = true; });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseHttpsRedirection();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
   endpoints.MapControllers();
   endpoints.MapHub<AlarmLogHub>("/alarmlog");
});
}
  1. Model实体代码
/// <summary>
/// 报警日志
/// </summary>
public class AlarmLogItem
{
public string Id { get; set; }
/// <summary>
/// 日志类型
/// </summary>
public AlarmLogType Type { get; set; }
/// <summary>
/// 日志名称
/// </summary>
public string Text { get; set; }
/// <summary>
/// 日志详细信息
/// </summary>
public string Description { get; set; }
/// <summary>
/// 日志更新时间
/// </summary>
public string UpdateTime { get; set; }
}

/// <summary>
/// 报警日志类型
/// </summary>
public enum AlarmLogType
{
Info,
Warn,
Error
}
3. 客户端代码
  • 客户端采用wpf创建,用于接收服务端推送的消息
  • 用nuget安装 Microsoft.AspNetCore.SignalR.Client
  • 前端页面MainWindow.xaml增加列表用于显示接收到的消息
<Grid>
    <ListBox x:Name="messagesList"  RenderTransformOrigin="-0.304,0.109" BorderThickness="1" BorderBrush="Gainsboro"/>
</Grid>
  • 后端MainWindow.xaml.cs的代码
public partial class MainWindow : Window
{
HubConnection connection;
public MainWindow()
{
InitializeComponent();
connection = new HubConnectionBuilder()
	.WithUrl("https://localhost:44334/alarmlog")
	.Build();
connection.Closed += async (error) =>
{
	await Task.Delay(new Random().Next(0, 5) * 1000);
	await connection.StartAsync();
};
connection.On<AlarmLogItem>("ReceiveAlarmLog", (message) =>
{
	this.Dispatcher.Invoke(() =>
	{
		messagesList.Items.Add(message.Description);
	});
});
try
{
	connection.StartAsync();
	messagesList.Items.Add("Connection started");
}
catch (Exception ex)
{
	messagesList.Items.Add(ex.Message);
}
}
}
4. 博客原文链接

使用SignalR从服务端主动推送警报日志到各种终端

5. 参考资料

史上最全面的SignalR系列教程

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值