【SignalR學習系列】3. SignalR實時高刷新率程式

来源:http://www.cnblogs.com/Soulless/archive/2017/07/22/7222891.html
-Advertisement-
Play Games

創建項目 創建一個空的 Web 項目,併在 Nuget 裡面添加 SignalR,jQuery UI 包,添加以後項目里包含了 jQuery,jQuery.UI ,和 SignalR 的腳本。 創建基礎應用 添加一個 SignalR Hub 類,並命名為 MoveShapeHub ,更新代碼。 當程 ...


創建項目

創建一個空的 Web 項目,併在 Nuget 裡面添加 SignalR,jQuery UI 包,添加以後項目里包含了 jQuery,jQuery.UI ,和 SignalR 的腳本。

 

創建基礎應用

添加一個 SignalR Hub 類,並命名為 MoveShapeHub ,更新代碼。

using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;

namespace SignalRDemo3
{
    public class MoveShapeHub : Hub
    {
        public void UpdateModel(ShapeModel clientModel)
        {
            clientModel.LastUpdatedBy = Context.ConnectionId;
            // Update the shape model within our broadcaster
            Clients.AllExcept(clientModel.LastUpdatedBy).updateShape(clientModel);
        }
    }

    public class ShapeModel
    {
        // We declare Left and Top as lowercase with 
        // JsonProperty to sync the client and server models
        [JsonProperty("left")]
        public double Left { get; set; }
        [JsonProperty("top")]
        public double Top { get; set; }
        // We don't want the client to get the "LastUpdatedBy" property
        [JsonIgnore]
        public string LastUpdatedBy { get; set; }
    }
}

當程式啟動的時候啟動Hub

添加 Owin 類,併在裡面配置 SignalR

using Microsoft.Owin;
using Owin;

[assembly: OwinStartup(typeof(SignalRDemo3.Startup))]

namespace SignalRDemo3
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=316888
            app.MapSignalR();
        }
    }
}

 

添加客戶端

添加一個名為 Index 的 html 頁面,並設置為啟動頁面。

<!DOCTYPE html>
<html>
<head>
    <title>SignalR MoveShape Demo</title>
    <style>
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    </style>
</head>
<body>
    <script src="Scripts/jquery-3.1.1.min.js"></script>
    <script src="Scripts/jquery-ui-1.12.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.2.js"></script>
    <script src="/signalr/hubs"></script>
    <script>
        $(function () {
            var moveShapeHub = $.connection.moveShapeHub,
                $shape = $("#shape"),
                shapeModel = {
                    left: 0,
                    top: 0
                };
            moveShapeHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        moveShapeHub.server.updateModel(shapeModel);
                    }
                });
            });
        });
    </script>

    <div id="shape" />
</body>
</html>

上面的 Html 和 JavaScript 代碼創建一個名為 Shape 的 Div ,並且通過jQuery庫給 Shape 提供了拖拽功能,並通過拖拽事件向伺服器發送 Shape 的當前位置。

現在可以 F5 啟動調試看效果,當程式啟動以後,打開另一個瀏覽器視窗,輸入地址,你可以在一個視窗拖拽紅色的 Shape,另一個視窗的 Shape 也會跟著動。

 

 

添加客戶端迴圈

如果每次滑鼠移動都發送數據到服務端,那就需要很多網路流量,我們必須降低發送數據的頻率。我們可以通過 setInterval 函數,設置一個固定的時間來發送數據到伺服器。

<!DOCTYPE html>
<html>
<head>
    <title>SignalR MoveShape Demo</title>
    <style>
        #shape {
            width: 100px;
            height: 100px;
            background-color: #FF0000;
        }
    </style>
</head>
<body>
    <script src="Scripts/jquery-3.1.1.min.js"></script>
    <script src="Scripts/jquery-ui-1.12.1.min.js"></script>
    <script src="Scripts/jquery.signalR-2.2.2.js"></script>
    <script src="/signalr/hubs"></script>
    <script>
        $(function () {
            var moveShapeHub = $.connection.moveShapeHub,
                $shape = $("#shape"),
                // Send a maximum of 2 messages per second
                // (mouse movements trigger a lot of messages)
                messageFrequency = 2,
                // Determine how often to send messages in
                // time to abide by the messageFrequency
                updateRate = 1000 / messageFrequency,
                shapeModel = {
                    left: 0,
                    top: 0
                },
                moved = false;
            moveShapeHub.client.updateShape = function (model) {
                shapeModel = model;
                $shape.css({ left: model.left, top: model.top });
            };
            $.connection.hub.start().done(function () {
                $shape.draggable({
                    drag: function () {
                        shapeModel = $shape.offset();
                        moved = true;
                    }
                });
                // Start the client side server update interval
                setInterval(updateServerModel, updateRate);
            });
            function updateServerModel() {
                // Only update server if we have a new movement
                if (moved) {
                    moveShapeHub.server.updateModel(shapeModel);
                    moved = false;
                }
            }
        });
    </script>

    <div id="shape" />
</body>
</html>

可以用上面的代碼更新剛纔的 Index.html頁面,然後F5調試,可以發現現在拖動一個 Shape 以後在另一個瀏覽器里的 Shape 半秒鐘才會更新。

 

增加服務端迴圈

更新 MoveShapeHub.cs

using Microsoft.AspNet.SignalR;
using Newtonsoft.Json;
using System;
using System.Threading;

namespace SignalRDemo3
{
    public class Broadcaster
    {
        private readonly static Lazy<Broadcaster> _instance =
            new Lazy<Broadcaster>(() => new Broadcaster());
        // We're going to broadcast to all clients once 2 second
        private readonly TimeSpan BroadcastInterval =
            TimeSpan.FromMilliseconds(2000);
        private readonly IHubContext _hubContext;
        private Timer _broadcastLoop;
        private ShapeModel _model;
        private bool _modelUpdated;
        public Broadcaster()
        {
            // Save our hub context so we can easily use it 
            // to send to its connected clients
            _hubContext = GlobalHost.ConnectionManager.GetHubContext<MoveShapeHub>();
            _model = new ShapeModel();
            _modelUpdated = false;
            // Start the broadcast loop
            _broadcastLoop = new Timer(
                BroadcastShape,
                null,
                BroadcastInterval,
                BroadcastInterval);
        }
        public void BroadcastShape(object state)
        {
            // No need to send anything if our model hasn't changed
            if (_modelUpdated)
            {
                // This is how we can access the Clients property 
                // in a static hub method or outside of the hub entirely
                _hubContext.Clients.AllExcept(_model.LastUpdatedBy).updateShape(_model);
                _modelUpdated = false;
            }
        }
        public void UpdateShape(ShapeModel clientModel)
        {
            _model = clientModel;
            _modelUpdated = true;
        }
        public static Broadcaster Instance
        {
            get
            {
                return _instance.Value;
            }
        }
    }

    public class MoveShapeHub : Hub
    {
        // Is set via the constructor on each creation
        private Broadcaster _broadcaster;
        public MoveShapeHub()
            : this(Broadcaster.Instance)
        {
        }
        public MoveShapeHub(Broadcaster broadcaster)
        {
            _broadcaster = broadcaster;
        }
        public void UpdateModel(ShapeModel clientModel)
        {
            clientModel.LastUpdatedBy = Context.ConnectionId;
            // Update the shape model within our broadcaster
            _broadcaster.UpdateShape(clientModel);
        }
    }

    public class ShapeModel
    {
        // We declare Left and Top as lowercase with 
        // JsonProperty to sync the client and server models
        [JsonProperty("left")]
        public double Left { get; set; }
        [JsonProperty("top")]
        public double Top { get; set; }
        // We don't want the client to get the "LastUpdatedBy" property
        [JsonIgnore]
        public string LastUpdatedBy { get; set; }
    }
}

上面的代碼新建了一個 Broadcaster 類,通過類 Timer 來進行節流。

因為 Hub 實例每次都會重新創建,所以只能創建一個 Broadcaster 的單例模型。調用客戶端 UpdateShape 的方法被移出了 hub 。現在它通過類 Broadcaster 來管理,通過名為 _broadcastLoop 的 timer 每兩秒更新一次。

最後因為不能直接在 hub 里調用客戶端方法,類 Broadcaster 需要通過 GlobalHost 來獲取到當前進行操作的 hub。

最終使用 F5 進行調試,雖然客戶端設置了半秒一次的刷新,但是因為伺服器端設置了2秒一次刷新,所以你在當前瀏覽器里移動 Shape ,兩秒鐘過後另一個瀏覽器里的 Shape 才會移動到當前位置。

 

源代碼鏈接:

鏈接: https://pan.baidu.com/s/1o8NXwTW 密碼: 5r5i

 

參考鏈接:

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/tutorial-high-frequency-realtime-with-signalr


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • fafa ...
  • 隨著用戶量和併發數的增加,單台伺服器出現了性能問題,此時必須要將應用程式和資料庫分離,分離後整個網站變成三台伺服器了:應用伺服器(或稱web伺服器),資料庫伺服器和文件伺服器。這三台伺服器對伺服器的配置要求是不一樣的,應用伺服器需要處理大量的業務邏輯,所以需要更快更強大的CPU,資料庫伺服器需要快速 ...
  • 初始階段的網站一般訪問量都很小(QPS<500),此時只需要一臺伺服器就足夠,應用程式,資料庫和文件都放在這一臺伺服器上。如果是.net的話,通常操作系統使用windows server,應用程式開發使用asp.net,然後應用程式部署在IIS上,資料庫使用sql server。 單機網站 單機網站 ...
  • 創建項目 創建一個空的 Web 項目,併在 Nuget 裡面添加 SignalR,jQuery UI 包,添加以後項目里包含了 jQuery,jQuery.UI ,和 SignalR 的腳本。 服務端代碼 創建 Stock 類 創建 tockTicker 和 StockTickerHub 類 添加類 ...
  • 最近一段時間在看樸靈翻譯的《深入淺出nodejs》,裡面有提到一種脫離瀏覽器的客戶端網路通訊工具,curl命令,自己在電腦上試了一下,感覺非常好用,而且莫名的感覺這是一個非常強大的網路工具,一定會成為web開發者的一把小軍刀;因此就上網查了一下相關資料,並整理了一下相關的常用用法: 一、簡介 CUR ...
  • 一、前言 對於不久開源的surging受到不少.net同學的青睞,也受到.net core學習小組的關註,邀請加入.NET China Foundation 以方便國內.net core開源項目的推廣,我果斷接受邀請加入了隊伍進行互相交流學習,最近也更新了surging新的版本 更新內容: 1. C ...
  • EF(Entity Framework的簡稱,下同)有三種方式,分別是:DataBase First、 Model First和Code First。 下麵是Db First的方式: 1. 資料庫庫中存在兩個表,一個是專業表,一個學生表,一個學生只能屬於一個專業: 其中T_Major是專業表,T_S ...
  • 騰訊推出微信小程式也有一段時間了,在各種行業裡面也都掀起一陣陣的熱潮,很多APP應用被簡化為小程式的功能迅速推出,同時也根據小程式的特性推出各種獨具匠心的應用,相對傳統的APP來說,微信小程式確實能夠大大降低開發成本和難度,但也意味著需要掌握整個微信小程式的各種介面功能、應用場景等相關技術點,本篇隨... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...