title: Observe WCF service call with RX
body: <p>I have a WCF heartbeat service accepting keep alives from clients. If keep alive does not arrive within specified time a timeout is raised and some action taken. Now, I'm trying to simplify existing code that uses System.Threading.Timer and replace it with a solution based on RX. What I'm missing is how to convert WCF service method class to observable. What I've considered are the following:</p>
  
  <ul>
  <li>Implementing IObservable in WCF service and cache observers passed as Subscribe parameters, probably not a good idea and ugly code</li>
  <li><p>Use Subject like this:
  <pre><code>
   Subject s1 = new Subject();
   s1.Timeout(TimeSpan.FromSeconds(3))
     .Subscribe(_ => { }, ex => Console.WriteLine("Timeout at " + DateTime.Now));</p>
  
  <p>Console.WriteLine("Hertbeat at: " + DateTime.Now);
   s1.OnNext(Unit.Default);
   Thread.Sleep(TimeSpan.FromSeconds(2));
   Console.WriteLine("Hertbeat at: " + DateTime.Now);
   s1.OnNext(Unit.Default);
  </pre></code>
  this works, but probably using subjects in production code is not a good idea.</p>
  
  <ul>
  <li>Use events in service's implementation: </li>
  </ul>
  
  <p><pre><code>
  class HeartbeatService
  {
    public void Heartbeat()
    {
      OnHeartbeatArrived();
    }</p>
  
  <p>public event Action HeartbeatArrived;</p>
  
  <p>protected virtual void OnHeartbeatArrived()
    {
  Action handler = HeartbeatArrived;
  if (handler != null) handler(Unit.Default);
    }
  }</pre></code></p></li>
  </ul>
  
  <p>and then use RX</p>
  
  <pre><code>HeartbeatService heartbeatService = new HeartbeatService();
  Observable.FromEvent&lt;Unit&gt;(action =&gt; heartbeatService.HeartbeatArrived += action,
                             action =&gt; heartbeatService.HeartbeatArrived -= action)
    .Timeout(TimeSpan.FromSeconds(3))
    .Subscribe(_ =&gt; { },
               ex =&gt; Console.WriteLine("Timeout " + ex + ", at " + DateTime.Now));
  
  Console.WriteLine("Heartbeat at: " + DateTime.Now);
  heartbeatService.Heartbeat();
  Thread.Sleep(TimeSpan.FromSeconds(2));
  Console.WriteLine("Heartbeat at: " + DateTime.Now);
  heartbeatService.Heartbeat();
  Console.WriteLine("Should timeout now");
  </code></pre>
  
  <p>I don't like this solution either, event in WCF service seems superfluous.
  Is there a good way of doing that in RX or maybe I'm trying to misuse RX here?</p>