利用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 ...
随机推荐
- 20184302 2019-2020-2 《Python程序设计》实验四报告
20184302 2019-2020-2 <Python程序设计>实验四报告 课程:<Python程序设计> 班级: 1843 姓名: 李新锐 学号:184302 实验教师:王 ...
- Android 图片裁剪踩坑
今天做图库图片的裁剪遇到了不少坑,今天记录一下,以下坑位供各位看官参考: 如果有不对之处,欢迎各位看官留言评论! 图片裁剪踩坑锦囊: 问题一:相册裁剪权限问题 解:这个简单,对于Android6. ...
- 在CentOS下利用Docker一键安装seafile
https://cloud.seafile.com/published/seafile-manual-cn/docker/pro-edition/%E7%94%A8Docker%E9%83%A8%E7 ...
- Nested Report_FR
设置好下面的关系(Mar 18做,copy from MyQ): 1) Customer.Orders.Items 的 MasterSouce.MasterField2) 后面2个的 DataSour ...
- CDN百科第四讲 | 如何优雅地在云上“摆摊”——做直播带货,你不得不关注的技术
最近,国家政策开始鼓励“地摊经济”,一时间各家企业平台纷纷推出地摊扶持政策,地摊概念股顺势大涨,地摊生态及配套商品也开始走俏,甚至在网络上也涌现出各种“新摊主速成攻略”,万亿的烟火经济俨然已经走上风口 ...
- nodejs 换源
解决npm install安装慢的问题国外镜像会很慢 可用 get命令查看registry npm config get registry 原版结果为 http://registry.npmjs.or ...
- Python基础002---基础知识
一.标识符 标识符是自己定义的,是开发人员在程序中自己定义的一些符号和名称,如变量名.函数名等.在 Python 里,标识符由字母(区分大小写).数字.下划线组成,且数字不能开头.常用的命名方法有小驼 ...
- 基于Web的监控系统的开发进行分布式和现代生产(外文翻译)
摘要 近年来,Web技术发展迅速.尤其是网络浏览器增强了其功能因为JavaScript,CSS3和HTML5的改进.因此,功能越来越丰富的基于Web的软件解决方案功能范围可用.通过使用响应式网页设计( ...
- CODING DevOps 系列第三课:云计算、云原生模式下 DevOps 的建设
本文首先会和大家分享当前整个应用生命周期的演变历程,然后讲解云计算模式下 DevOps 建设包含的过程.流程规范和标准,最后讲解云原生时代到来会带来哪些改变,以及标准化的建设会有哪些改变和突破. 应用 ...
- 使用IDEA+Gradle构建Spring5源码并调试(手把手教程全图解)
一.前言 说一说我要写这篇文章的初衷吧,前段时间有小伙伴在微信群求教怎样构建spring源码,他在网上找了n个教程跟着后面花了两天时间都没构建好,正好我最近因工作原因从mac换成windows,开 ...