从Web api操作调用SignalR hub

时间:2016-05-06 16:24:40

标签: signalr

基本上,我在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错误但没有任何反应。

非常感谢任何帮助。

0 个答案:

没有答案