2013-11-27 65 views
6

我有一個簡單的Web API,它返回一個Iobservable。我使用HttpClient獲取Observable,以便我可以訂閱它。我的問題是訂閱返回的Iobservable發出'空'結果。如何從Web API獲取IObservable

服務器

public IObservable<DataItem> GetDataItems() 
{ 
    return Observable.Generate(0, i => i < 10, i => i + 1, 
     i => new DataItem 
     { 
      Id = i, 
      Name = String.Format("Storage{0}",i) 
     }); 
} 

CLIENT

public IObservable<DataItem> GetDataItems() 
{ 
    using (HttpClient apiClient = new HttpClient()) 
    { 
     apiClient.BaseAddress = new Uri("http://localhost:9001"); 
     apiClient.DefaultRequestHeaders.Add("x-user-authentication", "xxxxxx"); 
     return apiClient 
      .GetAsync("api/xxxx/yyyy").Result.Content 
      .ReadAsAsync<DataItem>().ToObservable(); 
    } 
} 

var source = GetDataItems(); 

List<DataItem> items = new List<DataItem>(); 

IDisposable consoleSubscription = source.Subscribe(
      x => Console.WriteLine("{0}:{1}", x.Id, x.Name), 
      ex => Console.WriteLine("OnError : {0} ", ex.Message), 
      () => Console.WriteLine("Encountered End of Stream") 
      ); 
     consoleSubscription.Dispose(); 

我的問題是,我沒有得到任何數據從服務器返回。我得到一個'空'可觀察。我寫了一個針對我的控制器的單元測試,它確實返回了數據項。

任何建議,請幫助。無法理解我出錯的地方。服務器或客戶端上沒有錯誤。

回答

17

你有點雄心勃勃,期望IObservable<T>可以通過電線自動傳輸。恐怕WebAPI不會爲你做到這一點。

你所看到的是默認的json串行器輸出IObservable<T>的屬性的結果 - 也沒有,所以你得到空括號。

您的單元測試是可用的,因爲它全部在內存中 - 不會發生序列化/反序列化。

有使用HttpResponseMessage的StreamContent屬性流導致的出路,你可能橋/從IObservable<T> - 但它不是真正地道的WebAPI。 WebApi的異步支持實際上是針對服務器上的具有單項響應的請求進行異步處理,而不是連續返回流式事件。

底線是我認爲WebApi(至少在寫作的時候)在這裏是錯誤的技術選擇。你最好看看SignalR這是專門爲這種場景而構建的,並且包含在當前版本的ASP.NET中。它具有javascript和.NET客戶端支持,您可以很容易地橋接到IObservable<T>。有些人已經看過這個,比如in this post sporting example code

像我的通道Nirvana編輯:既然被Terracotta收購併包裝成通用消息一些example code可在其文檔中)的一些消息中間件,和CEP解決方案,如SQL服務器StreamInsight有出盒IObservable支持太。

+0

修復了Nirvana鏈接上的link-rot;兵馬俑買了它。 –

+0

Nirvana鏈接不起作用。 –

+0

我已更新它,並添加了一個樣本鏈接。 –