zoukankan      html  css  js  c++  java
  • 利用SignalR实施响应股票数据波动

    1.新建ASP.NET Web应用程序,  选择Empty模板。

    2.创建Stock.cs类

     1  public class Stock
     2     {
     3         /// <summary>
     4         /// 价格
     5         /// </summary>
     6         private decimal _price;
     7 
     8         /// <summary>
     9         /// 象征
    10         /// </summary>
    11         public string Symbol { get; set; }
    12 
    13         public decimal Price
    14         {
    15             get
    16             {
    17                 return _price;
    18             }
    19             set
    20             {
    21                 if (_price == value)
    22                 {
    23                     return;
    24                 }
    25 
    26                 _price = value;
    27 
    28                 if (DayOpen == 0)
    29                 {
    30                     DayOpen = _price;
    31                 }
    32             }
    33         }
    34         /// <summary>
    35         /// 开放
    36         /// </summary>
    37         public decimal DayOpen { get; private set; }
    38 
    39        /// <summary>
    40        /// 变动
    41        /// </summary>
    42         public decimal Change
    43         {
    44             get
    45             {
    46                 return Price - DayOpen;
    47             }
    48         }
    49 
    50         /// <summary>
    51         /// 变动百分比
    52         /// </summary>
    53         public double PercentChange
    54         {
    55             get
    56             {
    57                 return (double)Math.Round(Change / Price, 4);
    58             }
    59         }
    60     }
    Stock.cs

    3.选择程序包管理控制台,添加SignalR Nuget包

    输入命令 install-package Microsoft.AspNet.SignalR

    4.选择添加SignalR Hub Class(v2),命名StockTickerHub

    5.StockTickerHub.cs类

     1  [HubName("stockTickerMini")]
     2     public class StockTickerHub : Hub
     3     {
     4    private readonly StockTicker _stockTicker;
     5 
     6         public StockTickerHub() : this(StockTicker.Instance) { }
     7 
     8         public StockTickerHub(StockTicker stockTicker)
     9         {
    10             _stockTicker = stockTicker;
    11         }
    12 
    13         public IEnumerable<Stock> GetAllStocks()
    14         {
    15             return _stockTicker.GetAllStocks();
    16         }
    17     }
    StockTickerHub.cs

    6.添加StockTicker.cs类

     1   public class StockTicker
     2     {
     3         // 单例线程
     4         private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));
     5         private readonly ConcurrentDictionary<string, Stock> _stocks = new ConcurrentDictionary<string, Stock>();
     6         private readonly object _updateStockPricesLock = new object();
     7         private readonly double _rangePercent = .002;
     8         private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(250);
     9         private readonly Random _updateOrNotRandom = new Random();
    10         private readonly Timer _timer;
    11         //_updatingStockPrices标志被标记为volatile以确保对其进行线程安全访问。
    12         private volatile bool _updatingStockPrices = false;
    13 
    14         private StockTicker(IHubConnectionContext<dynamic> clients)
    15         {
    16 
    17             //构造函数使用一些示例股票数据初始化_stocks集合,
    18             //GetAllStocks返回股票。
    19             //这些股票集合又由StockTickerHub.GetAllStocks返回,
    20             //这是客户可以调用的Hub类中的服务器方法。
    21             Clients = clients;
    22             _stocks.Clear();
    23             var stocks = new List<Stock>
    24             {
    25                 new Stock { Symbol = "MSFT", Price = 30.31m },
    26                 new Stock { Symbol = "APPL", Price = 578.18m },
    27                 new Stock { Symbol = "GOOG", Price = 570.30m }
    28             };
    29             stocks.ForEach(stock => _stocks.TryAdd(stock.Symbol, stock));
    30 
    31             //构造函数启动一个Timer对象,
    32             //该对象定期调用随机更新股票价格的方法。
    33             _timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval);
    34 
    35         }
    36 
    37         public static StockTicker Instance
    38         {
    39             get
    40             {
    41                 return _instance.Value;
    42             }
    43         }
    44 
    45         private IHubConnectionContext<dynamic> Clients
    46         {
    47             get;
    48             set;
    49         }
    50 
    51         public IEnumerable<Stock> GetAllStocks()
    52         {
    53             return _stocks.Values;
    54         }
    55         private void UpdateStockPrices(object state)
    56         {
    57             lock (_updateStockPricesLock)
    58             {
    59                 if (!_updatingStockPrices)
    60                 {
    61                     _updatingStockPrices = true;
    62 
    63                     foreach (var stock in _stocks.Values)
    64                     {
    65                         if (TryUpdateStockPrice(stock))
    66                         {
    67                             BroadcastStockPrice(stock);
    68                         }
    69                     }
    70 
    71                     _updatingStockPrices = false;
    72                 }
    73             }
    74         }
    75         private bool TryUpdateStockPrice(Stock stock)
    76         {
    77             // Randomly choose whether to update this stock or not
    78             var r = _updateOrNotRandom.NextDouble();
    79             if (r > .1)
    80             {
    81                 return false;
    82             }
    83 
    84             // Update the stock price by a random factor of the range percent
    85             var random = new Random((int)Math.Floor(stock.Price));
    86             var percentChange = random.NextDouble() * _rangePercent;
    87             var pos = random.NextDouble() > .51;
    88             var change = Math.Round(stock.Price * (decimal)percentChange, 2);
    89             change = pos ? change : -change;
    90 
    91             stock.Price += change;
    92             return true;
    93         }
    94 
    95         private void BroadcastStockPrice(Stock stock)
    96         {
    97             Clients.All.updateStockPrice(stock);
    98         }
    99     }
    StockTicker.cs

    7.添加Startup.cs类

    1  public class Startup
    2     {
    3         public void Configuration(IAppBuilder app)
    4         {
    5             app.MapSignalR();
    6         }
    7     }
    Startup.cs

    8.设置前端代码

     1 <!DOCTYPE html>
     2 <html xmlns="http://www.w3.org/1999/xhtml">
     3 <head>
     4     <title>ASP.NET SignalR Stock Ticker</title>
     5     <style>
     6         body {
     7             font-family: 'Segoe UI', Arial, Helvetica, sans-serif;
     8             font-size: 16px;
     9         }
    10 
    11         #stockTable table {
    12             border-collapse: collapse;
    13         }
    14 
    15             #stockTable table th, #stockTable table td {
    16                 padding: 2px 6px;
    17             }
    18 
    19             #stockTable table td {
    20                 text-align: right;
    21             }
    22 
    23         #stockTable .loading td {
    24             text-align: left;
    25         }
    26 
    27         #stockTicker {
    28             overflow: hidden;
    29              450px;
    30             height: 24px;
    31             border: 1px solid #999;
    32         }
    33 
    34             #stockTicker .inner {
    35                  9999px;
    36             }
    37 
    38             #stockTicker ul {
    39                 display: inline-block;
    40                 list-style-type: none;
    41                 margin: 0;
    42                 padding: 0;
    43             }
    44 
    45             #stockTicker li {
    46                 display: inline-block;
    47                 margin-right: 8px;
    48             }
    49 
    50             /*<li data-symbol="{Symbol}"><span class="symbol">{Symbol}</span><span class="price">{Price}</span><span class="change">{PercentChange}</span></li>*/
    51             #stockTicker .symbol {
    52                 font-weight: bold;
    53             }
    54 
    55             #stockTicker .change {
    56                 font-style: italic;
    57             }
    58     </style>
    59 </head>
    60 <body>
    61     <h1>ASP.NET SignalR Stock Ticker Sample</h1>
    62 
    63     <h2>Live Stock Table</h2>
    64     <div id="stockTable">
    65         <table border="1">
    66             <thead>
    67                 <tr><th>Symbol</th><th>Price</th><th>Open</th><th>Change</th><th>%</th></tr>
    68             </thead>
    69             <tbody>
    70                 <tr class="loading"><td colspan="5">loading...</td></tr>
    71             </tbody>
    72         </table>
    73     </div>
    74 
    75     <!--Script references. -->
    76     <!--Reference the jQuery library. -->
    77     <script src="/Scripts/jquery-1.10.2.min.js"></script>
    78     <!--Reference the SignalR library. -->
    79     <script src="/Scripts/jquery.signalR-2.1.2.js"></script>
    80     <!--Reference the autogenerated SignalR hub script. -->
    81     <script src="/signalr/hubs"></script>
    82     <!--Reference the StockTicker script. -->
    83     <script src="StockTicker.js"></script>
    84 </body>
    85 </html>
    html

    9.创建StockTicker.js

     1 // A simple templating method for replacing placeholders enclosed in curly braces.
     2 if (!String.prototype.supplant) {
     3     String.prototype.supplant = function (o) {
     4         return this.replace(/{([^{}]*)}/g,
     5             function (a, b) {
     6                 var r = o[b];
     7                 return typeof r === 'string' || typeof r === 'number' ? r : a;
     8             }
     9         );
    10     };
    11 }
    12 
    13 $(function () {
    14 
    15     var ticker = $.connection.stockTickerMini, // the generated client-side hub proxy
    16         up = '',
    17         down = '',
    18         $stockTable = $('#stockTable'),
    19         $stockTableBody = $stockTable.find('tbody'),
    20         rowTemplate = '<tr data-symbol="{Symbol}"><td>{Symbol}</td><td>{Price}</td><td>{DayOpen}</td><td>{Direction} {Change}</td><td>{PercentChange}</td></tr>';
    21 
    22     function formatStock(stock) {
    23         return $.extend(stock, {
    24             Price: stock.Price.toFixed(2),
    25             PercentChange: (stock.PercentChange * 100).toFixed(2) + '%',
    26             Direction: stock.Change === 0 ? '' : stock.Change >= 0 ? up : down
    27         });
    28     }
    29 
    30     function init() {
    31         ticker.server.getAllStocks().done(function (stocks) {
    32             $stockTableBody.empty();
    33             $.each(stocks, function () {
    34                 var stock = formatStock(this);
    35                 $stockTableBody.append(rowTemplate.supplant(stock));
    36             });
    37         });
    38     }
    39 
    40     function scrollTicker() {
    41         var w = $stockTickerUl.width();
    42         $stockTickerUl.css({ marginLeft: w });
    43         $stockTickerUl.animate({ marginLeft: -w }, 15000, 'linear', scrollTicker);
    44     }
    45     // Add a client-side hub method that the server will call
    46     ticker.client.updateStockPrice = function (stock) {
    47         var displayStock = formatStock(stock),
    48             $row = $(rowTemplate.supplant(displayStock));
    49 
    50         $stockTableBody.find('tr[data-symbol=' + stock.Symbol + ']')
    51             .replaceWith($row);
    52     }
    53 
    54     // Start the connection
    55     $.connection.hub.start().done(init);
    56 
    57 });
    StockTicker.js

    10.最终效果

    具体可看微软官方:

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

    好好学习,天天向上。
  • 相关阅读:
    java基础部分的一些有意思的东西。
    antdvue按需加载插件babelpluginimport报错
    阿超的烦恼 javaScript篇
    .NET E F(Entity Framework)框架 DataBase First 和 Code First 简单用法。
    JQuery获得input ID相同但是type不同的方法
    gridview的删除,修改,数据绑定处理
    jgGrid数据格式
    Cannot read configuration file due to insufficient permissions
    Invoke action which type of result is JsonResult on controller from view using Ajax or geJSon
    Entity model数据库连接
  • 原文地址:https://www.cnblogs.com/Zhengxue/p/9025332.html
Copyright © 2011-2022 走看看