与Reactive Extensions的双向通信

时间:2014-03-31 13:03:07

标签: c# .net system.reactive reactive-programming

让我们想象一下,我有一个热门观察,是天气事件的来源。此源是与远程服务器的套接字连接,提供有关当前位置天气的信息。

该远程服务器还可以向我发送有关其他相关主题的事件,如流量,极端天气警告等...如果我发送命令来表明此愿望。

如何使用Reactive Extensions对此进行建模,而不在observable和observer之间创建耦合?

我的想法是,当我将ExtremeWeatherWarnings(观察者)订阅到我的WeatherServerConnection(可观察的)时,不知何故第一个向第二个发出一些命令,因此它启用了订阅。

我试图在观察者中实现一个特殊的接口,它告诉observable在订阅和取消订阅时需要执行的命令,但是当我在中间放置一个Where时它不起作用LINQ RX包装了observable,该包装器没有实现任何接口。

我还可以在WeatherServerConnection构造函数上要求ExtremeWeatherWarnings对象的实例,但这会产生耦合,我想避免这种情况。

干杯。

2 个答案:

答案 0 :(得分:3)

如果您的observable旨在发送通用消息,并且您的观察者正在设计翻译它们,那么您还需要一种向生产者指示您感兴趣的消息类型的方式。

这样做的一种方法是“请求观察”。

ObservableWeatherSource GetNotifications(WeatherWarnings warningTypes, string location);

另一种方法可能是懒洋洋地指出您感兴趣的通知。

ObservableWeatherSource source = GetWeatherSource();

source
    .Where(x => x.WeatherWarningType === WeatherWarnings.Rain)
    .Subscribe(new WeatherObserver());

source.ExpressInterestIn(WeatherWarnings.Rain, "San Francisco");

或者,您可能有兴趣为天气编写专门的查询语言。您可以通过IQbservable和查询提供程序执行此操作,但我对Rx的这个区域知之甚少。

答案 1 :(得分:1)

这完全取决于你对可观测量的看法。

如果它是独立于观察者的事件流,您可以将observable暴露给任何想要订阅的人。

这就是我在reactive GeoCoordinateWatcher上采用的方法。包装的GeoCoordinateWatcher class将生成独立于订阅的事件。

对于reactive Geolocator,我选择采用相同的方法。但是因为Geolocator需要参数化来生成事件,所以我可以选择实现一个可观察的工厂。

底线是(正如@Christopher所说)你将命令发送到暴露可观察物而不是观察物本身的东西。

通过应用 Rx 运算符,您可以执行类似命令向observable发送命令的操作。如果要远程应用这些过滤器,您可以实现(如@Christopher所说)IQbservale