使用SignalR发送实时通知

时间:2014-11-04 16:26:13

标签: asp.net tcp signalr

我想创建一个新系统,使用SignalR向用户发送实时交易执行消息。在旧系统中,每个客户端使用Java Applet TCP连接连接到交易服务器。

我使用以下教程作为参考 http://www.asp.net/signalr/overview/getting-started/tutorial-server-broadcast-with-signalr

StockTicker构造函数中有一行代码用于更新股票价格:

_timer = new Timer(UpdateStockPrices, null, _updateInterval, _updateInterval);

但是,我需要实时更新交易执行,而不是每250ms更新一次股票价格。 在构造函数中为每个客户端创建到我的交易服务器的TCP连接是否可以?似乎在示例代码中,StockTicker的构造函数(即我的TradingManager)将仅被调用一次。但在我的设计中,我想为每个客户端创建一个TCP连接。我该如何更改代码才能执行此操作?

这是我的代码:

TradingHub.cs

public class TradingHub : Hub
{
    private readonly TradingManager _tradingManager;
    public TradingHub() : this(TradingManager.Instance) { }

    public TradingHub(TradingManager tradingManager)
    {
        _tradingManager = tradingManager;
    }
    ...
}

TradingManager.cs

public class TradingManager
{
    // Singleton instance
    private readonly static Lazy<TradingManager> _instance = new Lazy<TradingManager>(
        () => new TradingManager());

    ...

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

    public TradingManager()
    {
        ...
        this.apiConnector.MessageReceived += new CustomEventHandler(this.api_MessageReceived);
        init();
    }

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

    private void init()
    {
        TradingSession tradingSession = getLoginSession(user);

        // connect to trading server using TCP connection
        this.apiConnector.ensureConnected(host, port, tradingSession);

        // send keep alive message to trading server periodically
        _timer = new Timer(sendKeepAlive, null, _updateInterval, _updateInterval);
    }

    private void api_MessageReceived(object sender, CustomEventArgs e)
    {
        // when web server receives trade execution from server, send out the message immediately
        Clients.Caller.SendTradeExecutionMessage(......);
    }

    public static TradingSession getLoginSession(string user)
    {
        ...
    }

    private void sendKeepAlive(object state)
    {
        ...
    }
}

1 个答案:

答案 0 :(得分:1)

如果您要在Hub构造函数中创建一个新的TradingManager而不是引用单例,那么您将为每个SignalR连接创建多个TradingManager。每次方法调用都会重新实例化集线器。每次调用hub方法或调用hub事件(例如OnConnected,OnReconnected,OnDisconnected)时,都会调用构造函数。

但是,每个SignalR连接只调用一次OnConnected。顺便说一下,SignalR连接与TCP连接完全正交。例如,使用长轮询传输时,每次收到消息时都会发送一个新的HTTP请求。

我想你想在每次调用OnConnected时创建一个新的TradingManager实例,并可能将它与客户端的Context.ConnectionId关联并存储它(可能在ConcurrentDictionary中),这样你就可以使用连接id检索它了。调用Hub方法。然后,您可以在OnDisconnected中取消引用存储的TradingManager实例以获取给定的连接ID。

您可以在以下位置了解有关SignalR连接的更多信息:

http://www.asp.net/signalr/overview/guide-to-the-api/handling-connection-lifetime-events

您可以在以下位置了解有关Hub API和On *方法的更多信息:

http://www.asp.net/signalr/overview/guide-to-the-api/hubs-api-guide-server#connectionlifetime