从SignalR消耗共享的IObservable

时间:2014-05-30 14:14:06

标签: c# asp.net signalr system.reactive

假设我有一个IObservable<Something>服务器端,存储在静态字段或其他任何内容中。

让我们假设我有一个具有Subscribe方法的SignalR中心和一个具有notify功能的signalR客户端。

public static IObservable<string> Events;
protected void Application_Start()
{
   //dummy observable just to generate events for me..
   Events = Observable
       .Timer(TimeSpan.Zero, TimeSpan.FromMilliseconds(50))
       .Select(l => l.ToString());
...snip..
}

public class MyHub1 : Hub
{        
    public void Subscribe()
    {
        Clients.All.notify("start");
        WebApiApplication.Events
            .Subscribe(s => Clients.Caller.notify(s));
    }
}

myHub.client.notify = function (event) {
     console.info(event);
};

我需要做些什么才能让所有客户共享可观察信息? 也就是说,我希望每个连接客户端在订阅后接收最后200个事件。然后每个客户端应该实时滴答相同的事件。

我想应该以某种方式使用IObservable的Replay方法。 我希望这个行为非常类似于聊天,用户可以实时查看最后的x条消息+每个新事件。

除了如何实际编写可观察查询外,在Asp.NET中存储和设置共享事件流的最佳方法是什么?

1 个答案:

答案 0 :(得分:5)

这是一个非常常见的架构问题 - 将直播流与世界状态相结合&#34;。您要做的是利用SignalR向当前订阅者广播实时消息(它擅长什么),并且有一个单独的API调用来加入客户端以获取历史消息。

在客户端中,您首先提供订阅实时SignalR消息流的逻辑,然后请求已经发生的消息的历史记录(&#34;世界状态&#34;) - 通常最好退回一个简单的有序列表。

存在一种固有的竞争条件,可能导致在直播和历史记录中收到消息 - 因此您必须注意重复删除或删除&#34;重复删除&#34;你的留言列表。

如何将持久消息作为一个完全独立的问题处理。

历史和现场直播的这种分离为你如何处理两者提供了灵活性,并提供了提高效率的机会,例如分页到历史,而不是抓住整个事物。

有一些问题和答案讨论了利用Rx结合历史数据和实时数据的方法 - 您需要在客户端javascript中执行此操作,而且我在rx js上并不是很好。

查看Merging historical and live stock price data with Rx有关此问题的一些讨论,以及Are these two Observable Operations Equivalent? - 我在后一种情况下有一些示例代码,这是纯粹的.NET场景。