asp.net - SignalR 使用组进行寻呼

标签 asp.net asp.net-mvc signalr signalr-hub signalr.client

我是 SignalR 的新手,在学习过程中,我正在尝试制作股票行情。我有超过 1000 只股票列表,并且想要显示分页并更新实时变化,这就是我将 Groups 与 SignalR 结合使用的原因。问题是,当我打开第 1 页时,一切正常,直到我打开第 2 页,然后第 1 页停止获取信号,第 2 页开始获取信号。我在 SignalR 组中缺少什么?请帮助我,谢谢。

中心

[HubName("stockTicker")]
public class StockTickerHub : Hub
{
    private StockTicker _stockTicker;

    public StockTickerHub()
        : this(StockTicker.Instance)
    {

    }

    public StockTickerHub(StockTicker stockTicker)
    {
        _stockTicker = stockTicker;
    }

    public void OpenMarket()
    {
        var page = this.Context.QueryString["page_no"];
        int pageno = Convert.ToInt32(page);
        _stockTicker.OpenMarket(pageno);
        tryAddGroup(page);
    }

    public Task tryAddGroup(string page)
    {
        return Groups.Add(Context.ConnectionId, page);
    }
}

StockTicker.cs

public class StockTicker
{

    MainModel _model = new MainModel();
    private static Lazy<StockTicker> _instance = new Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));
    private TimeSpan _updateInterval = TimeSpan.FromMilliseconds(3000);

    private Timer _timer;
    public volatile int pageno;
    private StockTicker(IHubConnectionContext<dynamic> clients)
    {
        Clients = clients;
    }

    public static StockTicker Instance
    {
        get
        {
            return _instance.Value;
        }
    }

    private IHubConnectionContext<dynamic> Clients
    {
        get;
        set;
    }


    public void OpenMarket(int page_no)
    {
        pageno = page_no;
        _timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
    }


    private void UpdateStockPrices(object state)
    {

        var latest_stocks = new List<StockViewModel>();
        latest_stocks = _model.Get100Stocks(pageno);
        foreach (var stock in latest_stocks)
        {
            BroadcastStockPrice(stock, pageno);
        }
    }
    private void BroadcastStockPrice(StockViewModel stock, int pageno)
    {
        Clients.Group(pageno.ToString()).updateStockPrice(stock);
        //Clients.All.updateStockPrice(stock);
    }
}

(更新的问题)

StockTicker.js

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;
            }
        );
    };
}

jQuery.fn.flash = function (color, duration) {
    var current = this.css('backgroundColor');
    this.animate({ backgroundColor: 'rgb(' + color + ')' }, duration / 2)
        .animate({ backgroundColor: current }, duration / 2);
};

$(function () {
    var ticker = $.connection.stockTicker;
    var $stockTable = $('#stockTable');
    var $stockTableBody = $stockTable.find('tbody');

    tdPrice = '<td data-rank-price="{currency_query}" data-sort="{currency_price_usd}"><div data-price-spn="{currency_query}">${currency_price_usd}</div></td>';
    tdPercentage = '<td data-rank-perc="{currency_query}" data-sort="{currency_change_24h_usd}"><div data-change-spn="{currency_query}"><span class="{DirectionClass}">{currency_change_24h_usd}</span></div></td>';
    tdVolume = '<td data-rank-volume="{currency_query}" data-sort="{currency_24h_volume_usd}"><div data-24-volume-spn="{currency_query}>${currency_24h_volume_usd}</div></td>';
    tdMarketcap = '<td data-rank-cap="{currency_query}" data-sort="{currency_market_cap_usd}"><div data-mcap-spn="{currency_query}">${currency_market_cap_usd}</div></td>';

    function formatStock(stock) {
        return $.extend(stock, {
            currency_price_usd: formatprices(stock.currency_price_usd),
            currency_change_24h_usd: stock.currency_change_24h_usd == null ? '0.00%' : (stock.currency_change_24h_usd).toFixed(2) + '%',
            currency_24h_volume_usd: stock.currency_24h_volume_usd == null ? '0' : nFormatter(stock.currency_24h_volume_usd, 2),
            currency_market_cap_usd: stock.currency_market_cap_usd == null ? '0' : nFormatter(stock.currency_market_cap_usd, 2),
            DirectionClass: stock.currency_change_24h_usd === 0 ? 'nochange' : stock.currency_change_24h_usd >= 0 ? 'green' : 'red'
        });
    }

    function nFormatter(num, digits) {
        var si = [
          { value: 1, symbol: "" },
          { value: 1E3, symbol: "K" },
          { value: 1E6, symbol: "M" },
          { value: 1E9, symbol: "B" },
          { value: 1E12, symbol: "T" },
          { value: 1E15, symbol: "P" },
          { value: 1E18, symbol: "E" }
        ];
        var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
        var i;
        for (i = si.length - 1; i > 0; i--) {
            if (num >= si[i].value) {
                break;
            }
        }
        return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
    }

    function formatprices(n, curr) {
        var sep = sep || ".";
        var decimals;
        if (n > 0.99999999) {
            decimals = decimals || 2;
        }
        else {
            decimals = decimals || 6;
        }

        return n.toLocaleString().split(sep)[0]
        + sep
        + n.toFixed(decimals).split(sep)[1];
    }

    $.extend(ticker.client, {
        updateStockPrice: function (stock) {
            var displayStock = formatStock(stock),
                $tdprice = $(tdPrice.supplant(displayStock)),
                $tdpercentage = $(tdPercentage.supplant(displayStock)),
                $tdvolume = $(tdVolume.supplant(displayStock)),
                $tdcap = $(tdMarketcap.supplant(displayStock));

            if (stock.LastChange != 0.0) {
                bgprice = stock.LastChange < 0.0
                        ? '255,148,148'
                        : '154,240,117';
                $stockTableBody.find('td[data-rank-price=' + stock.currency_query + ']').replaceWith($tdprice);
                $tdpricespn = $stockTableBody.find('div[data-price-spn=' + stock.currency_query + ']');
                $tdpricespn.flash(bgprice, 1500);
            }

            if (stock.LastChangePercentage != 0.0) {
                bgper = stock.LastChangePercentage < 0.0
                        ? '255,148,148'
                        : '154,240,117';
                $stockTableBody.find('td[data-rank-perc=' + stock.currency_query + ']').replaceWith($tdpercentage);
                $tdpercentagespn = $stockTableBody.find('div[data-change-spn=' + stock.currency_query + ']');
                $tdpercentagespn.flash(bgper, 1500);
            }

            if (stock.LastChangeVolume != 0.0) {
                bgvol = stock.LastChangeVolume < 0.0
                        ? '255,148,148'
                        : '154,240,117';
                $stockTableBody.find('td[data-rank-volume=' + stock.currency_query + ']').replaceWith($tdvolume);
                $tdvolumespn = $stockTableBody.find('div[data-24-volume-spn=' + stock.currency_query + ']');
                $tdvolumespn.flash(bgvol, 1500);
            }


            if (stock.LastChangeCap != 0.0) {
                bgcap = stock.LastChangeCap < 0.0
                        ? '255,148,148'
                        : '154,240,117';
                $stockTableBody.find('td[data-rank-cap=' + stock.currency_query + ']').replaceWith($tdcap);
                $tdcapspn = $stockTableBody.find('div[data-mcap-spn=' + stock.currency_query + ']');
                $tdcapspn.flash(bgcap, 1500);
            }
        }
    });

    $.connection.hub.url = 'http://localhost:13429/signalr';
    $.connection.hub.qs = { 'page_no': $("#page").val() };
    $.connection.hub.start().done(function () {
        console.log("connected");
    }).then(function () {
        return ticker.server.openMarket();
    });
});

最佳答案

查看您的代码,您的全局变量 pageno 始终是请求的最后一个页面:

 public void OpenMarket(int page_no)
    {
        pageno = page_no;
        _timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
    }

您需要另一个变量来跟踪最大页面。

 public volatile int pageMax;


public void OpenMarket(int page_no)
    {
        pageno = page_no;
        pageMax = pageno > pageMax
                  : pageno
                  ? pageMax;
        _timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
    }

然后确保将正确的股票广播到页面。

关于asp.net - SignalR 使用组进行寻呼,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49327950/

相关文章:

asp.net - 在 C# 中将 Base64 字节数组解码为图像

c# - 如何在面板内添加换行符或 html?

c# - EmailAddressAttribute 错误地将法语电子邮件地址归类为无效

wcf - 比较自托管 : WCF vs HttpListener

c# - Windows窗体与远程服务器之间如何实现实时数据同步

javascript - 用一个滚动条滚动两个 div (javascript)

jquery - 在 Web Api 2 中发帖

c# - 如何为路由注册区域

c# - Hub 在 SignalR 中代表什么

c# - SignalR 在集线器方法中等待很长时间