基本上,我在Azure Web作业侦听的队列中收到了一条消息。当新消息到达时,Web作业会为API操作创建Rest帖子。
我想拨打客户已注册的SignalR中心。此客户端是发起长时间运行进程请求的原始客户端。关于api操作,使用StockTicker示例,我添加了一个我在api操作中调用的新公共方法:
StockTicker.Instance.UpdateClient(value);
Hub类:
[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();
}
public void UpdateReportResult(ReportRequestKey key)
{
_stockTicker.UpdateReportResult(key);
}
}
StockTicker类:
public class StockTicker
{
private static readonly 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 = .002;
private readonly TimeSpan _updateInterval = TimeSpan.FromMilliseconds(250);
private readonly Random _updateOrNotRandom = new Random();
private readonly Timer _timer;
private volatile bool _updatingStockPrices = false;
private StockTicker(IHubConnectionContext<dynamic> clients)
{
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 = 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; }
public void UpdateReportResult(ReportRequestKey reportRequestKey)
{
Clients.All.updateReportResult(reportRequestKey);
}
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)
{
var r = _updateOrNotRandom.NextDouble();
if(r > .1)
return false;
var random = new Random((int)Math.Floor(stock.Price));
var percentageChange = random.NextDouble() * _rangePercent;
var pos = random.NextDouble() > .51;
var change = Math.Round(stock.Price * (decimal)percentageChange, 2);
change = pos ? change : -change;
stock.Price += change;
return true;
}
private void BroadcastStockPrice(Stock stock) { Clients.All.updateStockPrice(stock); }
}
StockTicker类上的UpdateClient方法将值广播到所有连接的客户端:
Clients.All.updateClient(value);
客户代码:
$(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>';
var $reportResultList = $('#generatedReportList'),
reporRowTemplate = '<li class="list-group-item">Node Id: {nodeId}, Request Correlation Id: {requestCorrelationId}, <input type="button" class="btn btn-default" value="Download Report" onclick="downloadReport({nodeId}, {requestCorrelationId})" /></li>';
function formatTemplate(reportResult) {
var string = reporRowTemplate.replace(/{nodeId}/g, reportResult.NodeId).replace(/{requestCorrelationId}/g, reportResult.RequestCorrelationId);
return string;
}
function formatStock(stock) {
return $.extend(stock, {
Price: stock.Price.toFixed(2),
PercentChange: (stock.PercentChange * 100).toFixed(2) + '%',
Direction: stock.Change === 0 ? '' : stock.Change >= 0 ? up : down
});
}
function init() {
ticker.server.getAllStocks().done(function (stocks) {
$stockTableBody.empty();
$.each(stocks, function () {
var stock = formatStock(this);
$stockTableBody.append(rowTemplate.supplant(stock));
});
});
}
// Add a client-side hub method that the server will call
ticker.client.updateReportResult = function (reportRequestKey) {
var displayReport = formatTemplate(reportRequestKey);
$reportResultList.append(displayReport);
}
// 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);
});
由于某种原因,我无法调用客户端消息。我在客户端或服务器上没有出现SignalR错误但没有任何反应。
非常感谢任何帮助。