假设我有一个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中存储和设置共享事件流的最佳方法是什么?
答案 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场景。