【SignalR学习系列】4. SignalR广播程序

转自:https://www.cnblogs.com/Soulless/p/7224442.html

创建项目

创建一个空的 Web 项目,并在 Nuget 里面添加 SignalR,jQuery UI 包,添加以后项目里包含了 jQuery,jQuery.UI ,和 SignalR 的脚本。

 

服务端代码

创建 Stock 类

复制代码
using System;

namespace SignalRDemo4
{
public class Stock
{
private decimal _price;

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">string</span> Symbol { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">decimal</span><span style="color: rgba(0, 0, 0, 1)"> Price
    {
        </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _price;
        }
        </span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (_price ==<span style="color: rgba(0, 0, 0, 1)"> value)
            {
                </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
            }

            _price </span>=<span style="color: rgba(0, 0, 0, 1)"> value;

            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (DayOpen == <span style="color: rgba(128, 0, 128, 1)">0</span><span style="color: rgba(0, 0, 0, 1)">)
            {
                DayOpen </span>=<span style="color: rgba(0, 0, 0, 1)"> _price;
            }
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">decimal</span> DayOpen { <span style="color: rgba(0, 0, 255, 1)">get</span>; <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">; }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">decimal</span><span style="color: rgba(0, 0, 0, 1)"> Change
    {
        </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> Price -<span style="color: rgba(0, 0, 0, 1)"> DayOpen;
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">double</span><span style="color: rgba(0, 0, 0, 1)"> PercentChange
    {
        </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> (<span style="color: rgba(0, 0, 255, 1)">double</span>)Math.Round(Change / Price, <span style="color: rgba(128, 0, 128, 1)">4</span><span style="color: rgba(0, 0, 0, 1)">);
        }
    }
}

}

复制代码

创建 tockTicker 和 StockTickerHub 类

添加类 StockTicker

复制代码
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Web;

namespace SignalRDemo4
{
public class StockTicker
{
// Singleton instance
private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> ConcurrentDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, Stock&gt; _stocks = <span style="color: rgba(0, 0, 255, 1)">new</span> ConcurrentDictionary&lt;<span style="color: rgba(0, 0, 255, 1)">string</span>, Stock&gt;<span style="color: rgba(0, 0, 0, 1)">();

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">object</span> _updateStockPricesLock = <span style="color: rgba(0, 0, 255, 1)">new</span> <span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)">();

    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">stock can go up or down by a percentage of this factor on each change</span>
    <span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> <span style="color: rgba(0, 0, 255, 1)">double</span> _rangePercent = .<span style="color: rgba(128, 0, 128, 1)">002</span><span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> TimeSpan _updateInterval = TimeSpan.FromMilliseconds(<span style="color: rgba(128, 0, 128, 1)">250</span><span style="color: rgba(0, 0, 0, 1)">);
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span> Random _updateOrNotRandom = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> Random();

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">readonly</span><span style="color: rgba(0, 0, 0, 1)"> Timer _timer;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">volatile</span> <span style="color: rgba(0, 0, 255, 1)">bool</span> _updatingStockPrices = <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> StockTicker(IHubConnectionContext&lt;<span style="color: rgba(0, 0, 255, 1)">dynamic</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> clients)
    {
        Clients </span>=<span style="color: rgba(0, 0, 0, 1)"> clients;

        _stocks.Clear();
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> stocks = <span style="color: rgba(0, 0, 255, 1)">new</span> List&lt;Stock&gt;<span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">new</span> Stock { Symbol = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MSFT</span><span style="color: rgba(128, 0, 0, 1)">"</span>, Price = <span style="color: rgba(128, 0, 128, 1)">30.31m</span><span style="color: rgba(0, 0, 0, 1)"> },
            </span><span style="color: rgba(0, 0, 255, 1)">new</span> Stock { Symbol = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">APPL</span><span style="color: rgba(128, 0, 0, 1)">"</span>, Price = <span style="color: rgba(128, 0, 128, 1)">578.18m</span><span style="color: rgba(0, 0, 0, 1)"> },
            </span><span style="color: rgba(0, 0, 255, 1)">new</span> Stock { Symbol = <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">GOOG</span><span style="color: rgba(128, 0, 0, 1)">"</span>, Price = <span style="color: rgba(128, 0, 128, 1)">570.30m</span><span style="color: rgba(0, 0, 0, 1)"> }
        };
        stocks.ForEach(stock </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> _stocks.TryAdd(stock.Symbol, stock));

        _timer </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> Timer(UpdateStockPrices, <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">, _updateInterval, _updateInterval);

    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span><span style="color: rgba(0, 0, 0, 1)"> StockTicker Instance
    {
        </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">
        {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _instance.Value;
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> IHubConnectionContext&lt;<span style="color: rgba(0, 0, 255, 1)">dynamic</span>&gt;<span style="color: rgba(0, 0, 0, 1)"> Clients
    {
        </span><span style="color: rgba(0, 0, 255, 1)">get</span><span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">set</span><span style="color: rgba(0, 0, 0, 1)">;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;Stock&gt;<span style="color: rgba(0, 0, 0, 1)"> GetAllStocks()
    {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _stocks.Values;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span> UpdateStockPrices(<span style="color: rgba(0, 0, 255, 1)">object</span><span style="color: rgba(0, 0, 0, 1)"> state)
    {
        </span><span style="color: rgba(0, 0, 255, 1)">lock</span><span style="color: rgba(0, 0, 0, 1)"> (_updateStockPricesLock)
        {
            </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">_updatingStockPrices)
            {
                _updatingStockPrices </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;

                </span><span style="color: rgba(0, 0, 255, 1)">foreach</span> (<span style="color: rgba(0, 0, 255, 1)">var</span> stock <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> _stocks.Values)
                {
                    </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (TryUpdateStockPrice(stock))
                    {
                        BroadcastStockPrice(stock);
                    }
                }

                _updatingStockPrices </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
            }
        }
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">bool</span><span style="color: rgba(0, 0, 0, 1)"> TryUpdateStockPrice(Stock stock)
    {
        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Randomly choose whether to update this stock or not</span>
        <span style="color: rgba(0, 0, 255, 1)">var</span> r =<span style="color: rgba(0, 0, 0, 1)"> _updateOrNotRandom.NextDouble();
        </span><span style="color: rgba(0, 0, 255, 1)">if</span> (r &gt; .<span style="color: rgba(128, 0, 128, 1)">1</span><span style="color: rgba(0, 0, 0, 1)">)
        {
            </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
        }

        </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Update the stock price by a random factor of the range percent</span>
        <span style="color: rgba(0, 0, 255, 1)">var</span> random = <span style="color: rgba(0, 0, 255, 1)">new</span> Random((<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)">)Math.Floor(stock.Price));
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> percentChange = random.NextDouble() *<span style="color: rgba(0, 0, 0, 1)"> _rangePercent;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> pos = random.NextDouble() &gt; .<span style="color: rgba(128, 0, 128, 1)">51</span><span style="color: rgba(0, 0, 0, 1)">;
        </span><span style="color: rgba(0, 0, 255, 1)">var</span> change = Math.Round(stock.Price * (<span style="color: rgba(0, 0, 255, 1)">decimal</span>)percentChange, <span style="color: rgba(128, 0, 128, 1)">2</span><span style="color: rgba(0, 0, 0, 1)">);
        change </span>= pos ? change : -<span style="color: rgba(0, 0, 0, 1)">change;

        stock.Price </span>+=<span style="color: rgba(0, 0, 0, 1)"> change;
        </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> BroadcastStockPrice(Stock stock)
    {
        Clients.All.updateStockPrice(stock);
    }
}

}

复制代码

为了线程安全,把 Stock 的数据存储在了 ConcurrentDictionary 里面。

 

添加 SignalR Hub Class

复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;

namespace SignalRDemo4
{
[HubName(“stockTickerMini”)]
public class StockTickerHub : Hub
{
private readonly StockTicker _stockTicker;

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> StockTickerHub() : <span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">(StockTicker.Instance) { }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> StockTickerHub(StockTicker stockTicker)
    {
        _stockTicker </span>=<span style="color: rgba(0, 0, 0, 1)"> stockTicker;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> IEnumerable&lt;Stock&gt;<span style="color: rgba(0, 0, 0, 1)"> GetAllStocks()
    {
        </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> _stockTicker.GetAllStocks();
    }
}

}

复制代码

添加 Owin 类,并在里面配置 SignalR

复制代码
using System;
using System.Threading.Tasks;
using Microsoft.Owin;
using Owin;

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

namespace SignalRDemo4
{
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();
}
}
}

复制代码

 

客户端代码

添加名为 StockTicker 的html页面,设置为启动页面,并替换为下面代码。

复制代码
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>ASP.NET SignalR Stock Ticker</title>
    <style>
        body {
            font-family: 'Segoe UI', Arial, Helvetica, sans-serif;
            font-size: 16px;
        }
    #stockTable table </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
        border-collapse</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> collapse</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">

        #stockTable table th, #stockTable table td </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            padding</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> 2px 6px</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">

        #stockTable table td </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
            text-align</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> right</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
        <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(128, 0, 0, 1)">

    #stockTable .loading td </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">{</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(255, 0, 0, 1)">
        text-align</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">:</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)"> left</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">;</span>
    <span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">}</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">style</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</head>
<body>
<h1>ASP.NET SignalR Stock Ticker Sample</h1>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">h2</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Live Stock Table<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">h2</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="stockTable"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">table </span><span style="color: rgba(255, 0, 0, 1)">border</span><span style="color: rgba(0, 0, 255, 1)">="1"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">thead</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Symbol<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Price<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Open<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>Change<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>%<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">th</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">thead</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tbody</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">tr </span><span style="color: rgba(255, 0, 0, 1)">class</span><span style="color: rgba(0, 0, 255, 1)">="loading"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;</span><span style="color: rgba(128, 0, 0, 1)">td </span><span style="color: rgba(255, 0, 0, 1)">colspan</span><span style="color: rgba(0, 0, 255, 1)">="5"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>loading...<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">td</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tr</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">tbody</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">table</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">Script references. </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">Reference the jQuery library. </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="Scripts/jquery-3.1.1.min.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">Reference the SignalR library. </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="Scripts/jquery.signalR-2.2.2.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">Reference the autogenerated SignalR hub script. </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="/signalr/hubs"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">Reference the StockTicker script. </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">src</span><span style="color: rgba(0, 0, 255, 1)">="Scripts/StockTicker.js"</span><span style="color: rgba(0, 0, 255, 1)">&gt;&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</body>
</html>

复制代码

添加名为 StockTicker 的js文件,并添加下面代码

复制代码
// A simple templating method for replacing placeholders enclosed in curly braces.
if (!String.prototype.supplant) {
    String.prototype.supplant = function (o) {
        return this.replace(/{([^{}]*)}/g,
            function (a, b) {
                var r = o[b];
                return typeof r === 'string' || typeof r === 'number' ? r : a;
            }
        );
    };
}

$(function () {

</span><span style="color: rgba(0, 0, 255, 1)">var</span> ticker = $.connection.stockTickerMini, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> the generated client-side hub proxy</span>
    up = '▲'<span style="color: rgba(0, 0, 0, 1)">,
    down </span>= '▼'<span style="color: rgba(0, 0, 0, 1)">,
    $stockTable </span>= $('#stockTable'<span style="color: rgba(0, 0, 0, 1)">),
    $stockTableBody </span>= $stockTable.find('tbody'<span style="color: rgba(0, 0, 0, 1)">),
    rowTemplate </span>= '&lt;tr data-symbol="{Symbol}"&gt;&lt;td&gt;{Symbol}&lt;/td&gt;&lt;td&gt;{Price}&lt;/td&gt;&lt;td&gt;{DayOpen}&lt;/td&gt;&lt;td&gt;{Direction} {Change}&lt;/td&gt;&lt;td&gt;{PercentChange}&lt;/td&gt;&lt;/tr&gt;'<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> formatStock(stock) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> $.extend(stock, {
        Price: stock.Price.toFixed(</span>2<span style="color: rgba(0, 0, 0, 1)">),
        PercentChange: (stock.PercentChange </span>* 100).toFixed(2) + '%'<span style="color: rgba(0, 0, 0, 1)">,
        Direction: stock.Change </span>=== 0 ? '' : stock.Change &gt;= 0 ?<span style="color: rgba(0, 0, 0, 1)"> up : down
    });
}

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> init() {
    ticker.server.getAllStocks().done(</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (stocks) {
        $stockTableBody.empty();
        $.each(stocks, </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> () {
            </span><span style="color: rgba(0, 0, 255, 1)">var</span> stock = formatStock(<span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
            $stockTableBody.append(rowTemplate.supplant(stock));
        });
    });
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Add a client-side hub method that the server will call</span>
ticker.client.updateStockPrice = <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> (stock) {
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> displayStock =<span style="color: rgba(0, 0, 0, 1)"> formatStock(stock),
        $row </span>=<span style="color: rgba(0, 0, 0, 1)"> $(rowTemplate.supplant(displayStock));

    $stockTableBody.find(</span>'tr[data-symbol=' + stock.Symbol + ']'<span style="color: rgba(0, 0, 0, 1)">)
        .replaceWith($row);
}

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Start the connection</span>

$.connection.hub.start().done(init);

});

复制代码

然后按F5进行调试,打开多个浏览器,发现里面的数据会同步更新。

 

源代码链接:

链接: https://pan.baidu.com/s/1pKRIR2r 密码: em9k

 

参考链接:

https://docs.microsoft.com/zh-cn/aspnet/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值