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

2.创建Stock.cs类

  public class Stock
{
/// <summary>
/// 价格
/// </summary>
private decimal _price; /// <summary>
/// 象征
/// </summary>
public string Symbol { get; set; } public decimal Price
{
get
{
return _price;
}
set
{
if (_price == value)
{
return;
} _price = value; if (DayOpen == )
{
DayOpen = _price;
}
}
}
/// <summary>
/// 开放
/// </summary>
public decimal DayOpen { get; private set; } /// <summary>
/// 变动
/// </summary>
public decimal Change
{
get
{
return Price - DayOpen;
}
} /// <summary>
/// 变动百分比
/// </summary>
public double PercentChange
{
get
{
return (double)Math.Round(Change / Price, );
}
}
}

Stock.cs

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

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

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

5.StockTickerHub.cs类

  [HubName("stockTickerMini")]
public class StockTickerHub : Hub
{
private readonly StockTicker _stockTicker; public StockTickerHub() : this(StockTicker.Instance) { } public StockTickerHub(StockTicker stockTicker)
{
_stockTicker = stockTicker;
} public IEnumerable<Stock> GetAllStocks()
{
return _stockTicker.GetAllStocks();
}
}

StockTickerHub.cs

6.添加StockTicker.cs类

   public class StockTicker
{
// 单例线程
private readonly static Lazy<StockTicker> _instance = new Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));
private readonly ConcurrentDictionary<string, Stock> _stocks = new ConcurrentDictionary<string, Stock>();
private readonly object _updateStockPricesLock = new object();
private readonly double _rangePercent = .;
private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds();
private readonly Random _updateOrNotRandom = new Random();
private readonly Timer _timer;
//_updatingStockPrices标志被标记为volatile以确保对其进行线程安全访问。
private volatile bool _updatingStockPrices = false; private StockTicker(IHubConnectionContext<dynamic> clients)
{ //构造函数使用一些示例股票数据初始化_stocks集合,
//GetAllStocks返回股票。
//这些股票集合又由StockTickerHub.GetAllStocks返回,
//这是客户可以调用的Hub类中的服务器方法。
Clients = clients;
_stocks.Clear();
var stocks = new List<Stock>
{
new Stock { Symbol = "MSFT", Price = 30.31m },
new Stock { Symbol = "APPL", Price = 578.18m },
new Stock { Symbol = "GOOG", Price = 570.30m }
};
stocks.ForEach(stock => _stocks.TryAdd(stock.Symbol, stock)); //构造函数启动一个Timer对象,
//该对象定期调用随机更新股票价格的方法。
_timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval); } public static StockTicker Instance
{
get
{
return _instance.Value;
}
} private IHubConnectionContext<dynamic> Clients
{
get;
set;
} public IEnumerable<Stock> GetAllStocks()
{
return _stocks.Values;
}
private void UpdateStockPrices(object state)
{
lock (_updateStockPricesLock)
{
if (!_updatingStockPrices)
{
_updatingStockPrices = true; foreach (var stock in _stocks.Values)
{
if (TryUpdateStockPrice(stock))
{
BroadcastStockPrice(stock);
}
} _updatingStockPrices = false;
}
}
}
private bool TryUpdateStockPrice(Stock stock)
{
// Randomly choose whether to update this stock or not
var r = _updateOrNotRandom.NextDouble();
if (r > .)
{
return false;
} // Update the stock price by a random factor of the range percent
var random = new Random((int)Math.Floor(stock.Price));
var percentChange = random.NextDouble() * _rangePercent;
var pos = random.NextDouble() > .;
var change = Math.Round(stock.Price * (decimal)percentChange, );
change = pos ? change : -change; stock.Price += change;
return true;
} private void BroadcastStockPrice(Stock stock)
{
Clients.All.updateStockPrice(stock);
}
}

StockTicker.cs

7.添加Startup.cs类

  public class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}

Startup.cs

8.设置前端代码

 <!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 {
border-collapse: collapse;
} #stockTable table th, #stockTable table td {
padding: 2px 6px;
} #stockTable table td {
text-align: right;
} #stockTable .loading td {
text-align: left;
} #stockTicker {
overflow: hidden;
width: 450px;
height: 24px;
border: 1px solid #;
} #stockTicker .inner {
width: 9999px;
} #stockTicker ul {
display: inline-block;
list-style-type: none;
margin: ;
padding: ;
} #stockTicker li {
display: inline-block;
margin-right: 8px;
} /*<li data-symbol="{Symbol}"><span class="symbol">{Symbol}</span><span class="price">{Price}</span><span class="change">{PercentChange}</span></li>*/
#stockTicker .symbol {
font-weight: bold;
} #stockTicker .change {
font-style: italic;
}
</style>
</head>
<body>
<h1>ASP.NET SignalR Stock Ticker Sample</h1> <h2>Live Stock Table</h2>
<div id="stockTable">
<table border="">
<thead>
<tr><th>Symbol</th><th>Price</th><th>Open</th><th>Change</th><th>%</th></tr>
</thead>
<tbody>
<tr class="loading"><td colspan="">loading...</td></tr>
</tbody>
</table>
</div> <!--Script references. -->
<!--Reference the jQuery library. -->
<script src="/Scripts/jquery-1.10.2.min.js"></script>
<!--Reference the SignalR library. -->
<script src="/Scripts/jquery.signalR-2.1.2.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="/signalr/hubs"></script>
<!--Reference the StockTicker script. -->
<script src="StockTicker.js"></script>
</body>
</html>

html

9.创建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 () { var ticker = $.connection.stockTickerMini, // the generated client-side hub proxy
up = '▲',
down = '▼',
$stockTable = $('#stockTable'),
$stockTableBody = $stockTable.find('tbody'),
rowTemplate = '<tr data-symbol="{Symbol}"><td>{Symbol}</td><td>{Price}</td><td>{DayOpen}</td><td>{Direction} {Change}</td><td>{PercentChange}</td></tr>'; function formatStock(stock) {
return $.extend(stock, {
Price: stock.Price.toFixed(),
PercentChange: (stock.PercentChange * ).toFixed() + '%',
Direction: stock.Change === ? '' : stock.Change >= ? up : down
});
} function init() {
ticker.server.getAllStocks().done(function (stocks) {
$stockTableBody.empty();
$.each(stocks, function () {
var stock = formatStock(this);
$stockTableBody.append(rowTemplate.supplant(stock));
});
});
} function scrollTicker() {
var w = $stockTickerUl.width();
$stockTickerUl.css({ marginLeft: w });
$stockTickerUl.animate({ marginLeft: -w }, , 'linear', scrollTicker);
}
// Add a client-side hub method that the server will call
ticker.client.updateStockPrice = function (stock) {
var displayStock = formatStock(stock),
$row = $(rowTemplate.supplant(displayStock)); $stockTableBody.find('tr[data-symbol=' + stock.Symbol + ']')
.replaceWith($row);
} // Start the connection
$.connection.hub.start().done(init); });

StockTicker.js

10.最终效果

具体可看微软官方:

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

最新文章

  1. css样式之 direction
  2. MVC5-8 ViewData、ViewBag、TempData分析
  3. Glusterfs分布式存储介绍(一)
  4. CentOS 7 终端设置屏幕分辨率
  5. HDU 5750 Dertouzos
  6. Java EE的十三种核心技术
  7. WIN32程序挂钩SetLastError,输出错误描述到控制台
  8. 原生js轮播图
  9. Undefined symbols for architecture arm64(其cpu架构)
  10. Android Framework 学习和需要学习的内容
  11. Manjaro折腾简单记录
  12. thinkPHP框架5.0 类图下载
  13. qmake使用方法(自动生成Makefile文件)
  14. 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr
  15. 回归JavaScript基础(五)
  16. java 对象和基本数据类型 “==”区别
  17. Eclipse默认快捷键指南
  18. Java基础知识:Java实现Map集合二级联动2
  19. Java隐藏手机号中间四位,隐藏身份证中间数字
  20. sun.misc.unsafe

热门文章

  1. 聊一聊高并发高可用那些事 - Kafka篇
  2. k8s学习-pod生命周期
  3. [windows][技巧]百度网盘提示您的电脑已安装百度网盘,是否覆盖,解决方法
  4. @loj - 2004@ 「SDOI2017」硬币游戏
  5. 排队I(替换两层复杂for循环、避免TLE)
  6. turtle 画一朵花
  7. Java中的map集合顺序如何与添加顺序一样
  8. @font-face规则指定字体
  9. input属性设置type=&quot;number&quot;之后, 仍可输入e;input限制只输入数字
  10. 【服务器】VMware Workstation Pro虚拟机搭建本地服务器CentOs7和宝塔面板(保姆式教程)