利用SignalR实施响应股票数据波动
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.最终效果

具体可看微软官方:
利用SignalR实施响应股票数据波动的更多相关文章
- Python爬虫抓取东方财富网股票数据并实现MySQL数据库存储
		
Python爬虫可以说是好玩又好用了.现想利用Python爬取网页股票数据保存到本地csv数据文件中,同时想把股票数据保存到MySQL数据库中.需求有了,剩下的就是实现了. 在开始之前,保证已经安装好 ...
 - 谈谈Java利用原始HttpURLConnection发送POST数据
		
这篇文章主要给大家介绍java利用原始httpUrlConnection发送post数据,设计到httpUrlConnection类的相关知识,感兴趣的朋友跟着小编一起学习吧 URLConnectio ...
 - 新浪实时股票数据接口http://hq.sinajs.cn/list=code
		
股票数据的获取目前有如下两种方法可以获取:1. http/javascript接口取数据2. web-service接口 1.http/javascript接口取数据1.1Sina股票数据接口以大秦铁 ...
 - 获取sina,baidu,google财经历史和实时股票数据接口
		
实时股票数据接口 股票数据的获取目前有如下两种方法可以获取:1. http/javascript接口取数据2. web-service接口1.http/javascript接口取数据1.1Sina股票 ...
 - Python爬虫 股票数据爬取
		
前一篇提到了与股票数据相关的可能几种数据情况,本篇接着上篇,介绍一下多个网页的数据爬取.目标抓取平安银行(000001)从1989年~2017年的全部财务数据. 数据源分析 地址分析 http://m ...
 - 用Python浅析股票数据
		
用Python浅析股票数据 本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略. 数据导入 这里将股票数据存储在stockData ...
 - 新浪实时股票数据接口http://hq.sinajs.cn/list=股票代码
		
股票数据的获取目前有如下两种方法可以获取: 1. http/JavaScript接口取数据 2. web-service接口 1.http/JavaScript接口取数据1.1Sina股票数据接口以大 ...
 - Python股票分析系列——基础股票数据操作(一).p3
		
该系列视频已经搬运至bilibili: 点击查看 欢迎来到Python for Finance教程系列的第3部分.在本教程中,我们将使用我们的股票数据进一步分解一些基本的数据操作和可视化.我们将要使用 ...
 - 【个人】爬虫实践,利用xpath方式爬取数据之爬取虾米音乐排行榜
		
实验网站:虾米音乐排行榜 网站地址:http://www.xiami.com/chart 难度系数:★☆☆☆☆ 依赖库:request.lxml的etree (安装lxml:pip install ...
 
随机推荐
- kebernets常用命令-整理
			
1.deployment相关命令 查看所有deployment: kubectl get deployments 查看指定命名空间的所有deployment: kubectl get deployme ...
 - “进大厂大半年,每个月都想走!”大公司 VS 小公司到底该如何选择?
			
前言 江湖风云不断,有人吐槽阿里996,也有人吐槽华为狼性文化,这不,就看到有腾讯员工吐槽“进腾讯大半年,每个月都想走!” “和我一样,进去一周就想走”.“我都陷入自我怀疑了,以为自己适应不了大公司” ...
 - MYSQL 实现ROWNO功能
			
select tt.rowno from( select (@rownum:=@rownum+1) as rowno, t.id from news t ,(select (@rownum : ...
 - 前端JS的服务订阅&服务发布
			
var eventCenter = { sub:function(mesName, mesCallback){ this.argus=this.argus||{}; this.argus[mesNam ...
 - 百度编辑器UEditor不能插入视频的解决方法
			
在编辑器中就可以引用优酷.腾讯视频的iframe通用代码和embed html代码:移动端一般引用iframe,可设置属性,使其适应设备.(这里,建议切换到源码模式,插入相应的视频代码embed或if ...
 - 关于宝塔面板ftp+sublime
			
如果sublime通过ftp上传文件传不上去,我的问题在于应该把sftp-config.json中"remote_path": "/",设置成这样.一下午.哎呀 ...
 - 【Navicat】Navicat for MongoDBv15.0.6破解版(附破解教程)
			
安装包下载链接:https://download.csdn.net/download/l1028386804/12519681 Navicat for MongoDB 15是一款功能十分强大的数据库管 ...
 - @topcoder - SRM614D1L3@ TorusSailing
			
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N*M 的方格图,某人从 (0, 0) 出发想要走到 ...
 - python常用模块-os
			
得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd() 返回指定目录下的所有文件和目录名:os.listdir() 函数用来删除一个文件:os.remove() 删除多个目录 ...
 - iOS视频随笔(一)
			
实例化对象init [AFNetworkActivityIndicatiorManager shareManager].enable = Yes; //开启网络请求指示 scrollView.cont ...