使用SignalR技术实现监控刷新功能
我是CHARSET,转载请保留全文本。
-
建立POCO
public class Eventing : EventArgs { public DateTime EmitTime { get; set; } public string? Message { get; set; } } public class SampleEvent : Eventing { public int Success { get; set; } public int Fail { get; set; } }
-
建立能发送SignalR的服务接口
public interface ICacheQueueService<T> where T: EventArgs { Task AddThenSend(T t); List<T> Get(); } public interface ICacheObjectService<T> where T: EventArgs { Task UpdateThenSend(T t); T Get(); }
-
实现接口
public class CacheQueueService<T> : ICacheQueueService<T> where T: EventArgs { readonly ConcurrentQueue<T> events = new(); readonly IHubContext<Whisper> hubContext; readonly int queueDepth = 20; readonly string name = $"{nameof(CacheQueueService<T>)}<{typeof(T).Name}>"; //忽略DI过程 public async Task AddThenSend(T t) { events.Enqueue(t); while (events.Count > queuDepth) event.TryDequeue(out var _); await hubContext.Clients.All.SendAsync(name, t); } public List<T> Get() => events.ToList(); } public class CacheObjectService<T> : ICacheObjectService<T> where T: EventArgs { //同上 readonly string name = $"{nameof(CacheObjectService<T>)}<{typeof(T).Name}>"; readonly T _t = new(); readonly EmitCloneService clone; public async Task UpdateThenSend(T t) { clone.Clone(T, _t); await hubContext.Clients.All.SendAsync(name, t); } }
-
关于
EmitCloneService
public class EmitCloneService { readonly Dictionary<Type, Delegate> cachedIL = new(); public void Clone<T>(T source, T target) { if (source is null || target is null) return; var type = typeof(T); if (!cachedIL.TryGetValue(type, out var @delegate)) { var dynamicMethod = new DynamicMethod("Clone", null, new[] { type, type }); var il = dynamicMethod.GetILGenerator(); foreach(var property in type.GetProperties()) { if (property.CanRead && property.CanWrite && !property.GetAccessor(true)[0].IsStatic) { il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, property.GetMethod); il.Emit(OpCodes.Callvirt, property.SetMethod); } } il.Emit(OpCodes.Ret); var clone = (Action<T, T>)dynamicMethod.CreateDelegate(typeof(Action<T, T>)); cachedIL.Add(type, clone); clone(source, target); } else { ((Action<T, T>)@delegate)(source, target); } } }
-
注册服务
services.AddSingleton<ICacheObjectSerivce<SampleEvent>, CacheObjectService<SampleEvent>>();
-
编写Razor页面(页面组件使用AntDesign Blazor)
@inject ICacheObjectService<SampleEvent> Sample //... <Card Title="Sample" Style="width:300px"> <Extra>@Sample.EmitTime</Extra> <Body> <Badge Count=@Sample.Success ShowZero Style="background-color:limegreen" /> <Badge Count=@Sample.Fail ShowZero Style="background-color:orangered" /> </Body> </Card> //...
-
在Razor页面的操作
readonly SampleEvent Sample = new(); protected override async Task OnInitializedAsync() { hubConnection = new HubConnectionBuilder().WithUrl(NavigationManager.ToAbsoluteUri("/whisper")).Build(); var sampleEventName = $"{nameof(CacheObjectService<T>)}<{nameof(SampleEvent)}>"; hubConnection.On<SampleEvent>(name, sample => { Sample.EmitTime = sample.EmitTime; Sample.Success = sample.Success; Sample.Fail = sample.Fail; }); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)