亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

WPF+ASP.NET SignalR實現(xiàn)動態(tài)折線圖的繪制

 更新時間:2023年01月03日 14:26:30   作者:小六公子  
這篇文章將以一個簡單的動態(tài)折線圖示例,簡述如何通過ASP.NET SignalR實現(xiàn)后臺通知功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下

在實際業(yè)務中,當后臺數(shù)據(jù)發(fā)生變化,客戶端能夠?qū)崟r的收到通知,而不是由用戶主動的進行頁面刷新才能查看,這將是一個非常人性化的設計。有沒有那么一種場景,后臺數(shù)據(jù)明明已經(jīng)發(fā)生變化了,前臺卻因為沒有及時刷新,而導致頁面顯示的數(shù)據(jù)與實際存在差異,從而造成錯誤的判斷。那么如何才能在后臺數(shù)據(jù)變更時及時通知客戶端呢?本文以一個簡單的動態(tài)折線圖示例,簡述如何通過ASP.NET SignalR實現(xiàn)后臺通知功能,僅供學習分享使用,如有不足之處,還請指正。

什么是SignalR

 ASP.NET SignalR 是一個面向 ASP.NET 開發(fā)人員的庫,可簡化將實時 web 功能添加到應用程序的過程。 實時 web 功能是讓服務器代碼將內(nèi)容推送到連接的客戶端立即可用,而不是讓服務器等待客戶端請求新數(shù)據(jù)的能力。

SignalR做了什么

傳統(tǒng)HTTP采用的是大家熟知的“拉模式”,即客戶端發(fā)出的每次請求,服務端都是被動處理。此場景下客戶端是老大,很顯然只有一方主動,操作與處理起來就沒那么完美。

為了能讓服務端也能主動,html5的出現(xiàn)讓這種變得可能,大家知道html5中有兩種主動模式。第一種叫做websockect,WebSockets是Html5提供的新的API,可以在Web網(wǎng)頁與服務器端間建立Socket連接,它是基于tcp模式的雙工通訊。還有一種叫做SSE,也就是客戶端來訂閱服務器的一種事件模型。

在html5出來之前,如果要做到服務器主動,我們只能采用變相的longpool和iframe流勉強實現(xiàn)。

SignalR對上面四種方案進行了高度的封裝,也就是說signalR會在這四種技術中根據(jù)瀏覽器和服務器設置采取最優(yōu)的一種模式。

封裝與集成

對于.NET開發(fā)者的福音,.NET平臺為我們提供了一種簡潔高效智能的實時信息交互技術->SignalR,它集成了上述數(shù)種技術,并能根據(jù)配置自動或手動選擇其最佳應用。

SignalR用途

SignalR 提供了一個簡單的 API,用于創(chuàng)建服務器到客戶端遠程過程調(diào)用 (RPC) ,該調(diào)用客戶端瀏覽器 (和其他客戶端平臺中的 JavaScript 函數(shù)) 服務器端 .NET 代碼。 SignalR 還包括用于連接管理的 API (,例如連接和斷開連接事件) ,以及分組連接。

雖然聊天通常被用作示例,但你可以做更多的事情。每當用戶刷新網(wǎng)頁以查看新數(shù)據(jù)時,或者該網(wǎng)頁實施 Ajax 長輪詢以檢索新數(shù)據(jù)時,它都是使用 SignalR 的候選者。SignalR 還支持需要從服務器進行高頻更新的全新類型的應用,例如實時游戲。

官方網(wǎng)址和源碼

官方網(wǎng)址:https://dotnet.microsoft.com/zh-cn/apps/aspnet/signalr

微軟API文檔:https://learn.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/introduction-to-signalr

GitHub網(wǎng)址:https://github.com/SignalR

示例截圖

本示例主要實現(xiàn)一個動態(tài)折線圖功能,主要分為服務端和客戶端兩部分,示例如下所示:

服務端項目創(chuàng)建

1. 創(chuàng)建一個Web服務端程序(以ASP.NET WebApi為例),默認情況下SignalR已經(jīng)作為項目框架的一部分而存在,所以不需要安裝,直接使用即可。通過項目--依賴性--框架--Microsoft.AspNetCore.App可以查看

2. 創(chuàng)建ChatHub,繼承Hub基類,作為后臺連接管理的中心

using Microsoft.AspNetCore.SignalR;

namespace DemoSignalR.Server.Chat
{
    public class ChatHub : Hub
    {
        #region 連接和斷開連接

        public override async Task OnConnectedAsync()
        {
            var connId = Context.ConnectionId;
            Console.WriteLine($"{connId} 已連接");
            await base.OnConnectedAsync();
        }

        public void StartNotify(string type)
        {
            if (type == "1")
            {

            }
            else if (type == "2")
            {

            };

        }

        public override async Task OnDisconnectedAsync(Exception ex)
        {
            //如果斷開連接
            var connId = Context.ConnectionId;
            Console.WriteLine($"{connId} 已斷開");
            await base.OnDisconnectedAsync(ex);
        }

        #endregion
    }
}

SignalR服務端業(yè)務集成

在實際業(yè)務中,存在各種需要后臺通知的功能,根據(jù)不同的業(yè)務,可以采用不同的通知觸發(fā)方式:

1. 在調(diào)用接口時觸發(fā)后臺通知

using DemoSignalR.Server.Chat;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace DemoSignalR.Server.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class TestWebApiController : ControllerBase
    {


        private readonly ILogger<TestWebApiController> _logger;

        private IHubContext<ChatHub> _context;

        public TestWebApiController(ILogger<TestWebApiController> logger, IHubContext<ChatHub> context)
        {
            _logger = logger;
            _context = context;
        }

        [HttpGet]
        public void GetTestA(string Name)
        {
            string info = $"當前接收到的信息為:{Name},{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}";
            _context.Clients.All.SendAsync("", info);
        }


    }
}

2. 定時器循環(huán)通知

using Microsoft.AspNetCore.SignalR;
using System.Timers;

namespace DemoSignalR.Server.Chat
{
    public class TestChatInfo
    {
        private IHubContext<ChatHub> _context;

        private System.Timers.Timer _timer;

        private readonly static object locker = new object();//鎖對象

        public static TestChatInfo instance;//當前實例

        private readonly ILogger _logger;

        private int _index = 0;

        private TestChatInfo(IHubContext<ChatHub> _context, ILogger _logger)
        {
            this._context = _context;
            this._logger = _logger;
            //定義定時器
            _timer = new System.Timers.Timer(100);
            _timer.AutoReset = true;
            _timer.Enabled = true;
            _timer.Elapsed += Timer_Elapsed;
            _timer.Start();
        }

        private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
        {
            //業(yè)務邏輯判斷
            var obj = new TestValue();
            obj.Index = this._index;
            obj.Value = DateTime.Now.Millisecond % 100;
            _context.Clients.All.SendAsync("RefreshInfos", obj);
            this._index++;
        }

        /// <summary>
        /// 注冊,即初始化單例實例
        /// </summary>
        /// <param name="context"></param>
        /// <param name="reviewTaskService"></param>
        /// <param name="sysParamService"></param>
        public static void Register(IHubContext<ChatHub> context, ILogger logger)
        {
            lock (locker)
            {
                if (instance == null)
                {
                    lock (locker)
                    {
                        instance = new TestChatInfo(context, logger);
                    }
                }
            }
        }

    }

    public class TestValue
    {
        private int index;
        public int Index { get { return index; } set { index = value; } }

        private float value;
        public float Value { get { return value; } set { this.value = value; } }
    }
}

SignalR服務端配置

 SignalR服務端配置主要分成三步:

1. 添加SignalR服務

2. 映射SignalR路由

3. 注冊單例后臺通知服務(如果其他方式,可省略)

using DemoSignalR.Server.Chat;
using Microsoft.AspNetCore.SignalR;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
//1.添加SignalR服務
builder.Services.AddSignalR();
builder.Services.AddLogging(logging => logging.AddConsole());

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}
app.UseRouting();
app.UseHttpsRedirection();

app.UseAuthorization();


//在Use中注冊單例實例
app.Use(async (context, next) =>
{
    var hubContext = context.RequestServices.GetRequiredService<IHubContext<ChatHub>>();
    //var logger = context.RequestServices.GetRequiredService<ILogger>();
    TestChatInfo.Register(hubContext, null);//調(diào)用靜態(tài)方法注冊
    if (next != null)
    {
        await next.Invoke();
    }
});

app.MapControllers();

//2.映射路由
app.UseEndpoints(endpoints => {
    endpoints.MapHub<ChatHub>("/chat");
});

app.Run();

客戶端項目創(chuàng)建

1. 創(chuàng)建WPF項目

2. 通過NuGet包管理器安裝SignalR客戶端

3. 創(chuàng)建SignalR狀態(tài)管理,主要管理SignalR的連接,關閉,重連等操作。

using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoSignalR.Client
{
    internal class SignalRClient
    {
        private readonly HubConnection hubConnection;

        public HubConnection HubConnection
        {
            get { return hubConnection; }
        }

        public SignalRClient()
        {
            var server = ConfigurationManager.AppSettings["Server"].ToString();
            hubConnection = new HubConnectionBuilder().WithUrl($"{server}/chat").WithAutomaticReconnect().Build();
            hubConnection.KeepAliveInterval = TimeSpan.FromSeconds(5);
        }

        public virtual void Listen()
        {

        }

        public async void Start()
        {
            try
            {
                await hubConnection.StartAsync();

            }
            catch (Exception e)
            {

            }
        }
    }
}

客戶端業(yè)務邏輯處理

1. 根據(jù)不同的業(yè)務邏輯分別監(jiān)聽不同的通知事件。

2. 示例詳見源碼

using Microsoft.AspNetCore.SignalR.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DemoSignalR.Client
{
    internal class TestSignalRClient : SignalRClient
    {
        public Action<object> RefreshInfos;

        public Action<string> Reconnected;

        public TestSignalRClient() : base()
        {
        }

        public override void Listen()
        {
            HubConnection.On<object>("RefreshInfos", (obj) =>
            {
                //
                if (obj != null)
                {
                    Console.WriteLine("收到數(shù)據(jù)");
                    //發(fā)送消息
                    if (RefreshInfos != null)
                    {
                        RefreshInfos(obj);
                    }
                }
            });
            HubConnection.Reconnected += HubConnection_Reconnected;
        }

        private Task HubConnection_Reconnected(string arg)
        {
            return Task.Run(() =>
            {
                if (Reconnected != null)
                {
                    Reconnected(arg);
                }
            });
        }

        public virtual void StartNotify(string condition)
        {
            HubConnection.SendAsync("StartNotify", condition);
            Console.WriteLine($"開始通過知{condition}");
        }
    }
}

SignalR需要注意事項

你不會實例化 Hub 類或從服務器上自己的代碼調(diào)用其方法;由 SignalR Hubs 管道為你完成的所有操作。 SignalR 每次需要處理中心操作(例如客戶端連接、斷開連接或向服務器發(fā)出方法調(diào)用時)時,SignalR 都會創(chuàng)建 Hub 類的新實例。

由于 Hub 類的實例是暫時性的,因此無法使用它們來維護從一個方法調(diào)用到下一個方法的狀態(tài)。 每當服務器從客戶端收到方法調(diào)用時,中心類的新實例都會處理消息。 若要通過多個連接和方法調(diào)用來維護狀態(tài),請使用一些其他方法(例如數(shù)據(jù)庫)或 Hub 類上的靜態(tài)變量,或者不派生自 Hub的其他類。 如果在內(nèi)存中保留數(shù)據(jù),請使用 Hub 類上的靜態(tài)變量等方法,則應用域回收時數(shù)據(jù)將丟失。

如果要從在 Hub 類外部運行的代碼將消息發(fā)送到客戶端,則無法通過實例化 Hub 類實例來執(zhí)行此操作,但可以通過獲取對 Hub 類的 SignalR 上下文對象的引用來執(zhí)行此操作。

注意:ChatHub每次調(diào)用都是一個新的實例,所以不可以有私有屬性或變量,不可以保存對像的值,所以如果需要記錄一些持久保存的值,則可以采用靜態(tài)變量,或者中心以外的對象。

關于源碼

本示例中相關源碼,已上傳至gitee(碼云),鏈接如下:https://gitee.com/ahsiang/demo-signal-r

以上就是WPF+ASP.NET SignalR實現(xiàn)動態(tài)折線圖的繪制的詳細內(nèi)容,更多關于WPF繪制動態(tài)折線圖的資料請關注腳本之家其它相關文章!

相關文章

最新評論