2016-02-17 61 views
0

我想將我的數據從web API推送到客戶端,所以我在Web API中使用PushStreamContent。 我的數據都是學生存在數據庫中。PushStreamContent Web API

public HttpResponseMessage GetAll() 
    { 
     HttpResponseMessage response = new HttpResponseMessage(); 
     var students = _symboleService.GetAll(); 
     response.Content = new PushStreamContent((students, httpContent, context) => 
     { 
      OnStreamAvailable(students, httpContent, context); 
     }, "text/plain"); 
     return response; 

    } 

    private void OnStreamAvailable(Stream stream, HttpContent content,TransportContext context) 
    { 
     StreamWriter responseStreamWriter = new StreamWriter(stream); 
     clients.Add(responseStreamWriter); 
    } 

但錯誤顯示在該線上的「學生」:

response.Content = new PushStreamContent((students, httpContent, context) => 

本地或命名參數「學生」不能在此範圍 聲明,因爲這個名字是在使用包圍本地範圍以限定 本地或參數

更新我在這裏的要點是將數據推送到客戶端, 一些修改後,該我的代碼,但它示出了在線路錯誤時,需要用於非靜態字段

var students = _symboleService.GetAll(); 

的對象引用,方法或 財產 'SymbolesController._symboleService'

private static readonly Lazy<Timer> _timer = new Lazy<Timer>(() => new Timer(TimerCallback, null, 0, 1000)); 
    private static readonly ConcurrentDictionary<StreamWriter, StreamWriter> _outputs = new ConcurrentDictionary<StreamWriter, StreamWriter>(); 

    public HttpResponseMessage GetAll() 
    { 
     HttpResponseMessage response = new HttpResponseMessage(); 
     response.Content = new PushStreamContent((responseStream, httpContent, context) => 
     { 
      StreamWriter responseStreamWriter = new StreamWriter(responseStream); 

      _outputs.TryAdd(responseStreamWriter, responseStreamWriter); 

     }, "text/plain"); 

     Timer t = _timer.Value; 

     return response; 
    } 



    // Runs every second after the first request to this controller and 
    // writes to the response streams of all currently active requests 
    private static void TimerCallback(object state) 
    { 

     foreach (var kvp in _outputs.ToArray()) 
     { 
      StreamWriter responseStreamWriter = kvp.Value; 

      try 
      { 
       var students = _symboleService.GetAll(); 
       responseStreamWriter.Write(students); 
       responseStreamWriter.Flush(); 
      } 
      catch { } 
     } 
    } 

順便說一句,如果我在這裏改變studentsby DateTime.Now,它的工作原理:

responseStreamWriter.Write(students); to 
responseStreamWriter.Write(DateTime.Now); 
+1

這聽起來像你試圖實施推送消息範例。你可能想看看SignalR。 http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr –

+0

我看到它晚了,我的代碼差不多完成了,也許我稍後會看到它,thnx – Juste3alfaz

回答

3

您需要重命名PushStreamContent構造函數中使用的students參數。

例如,來自:

response.Content = new PushStreamContent((students, httpContent, context) => 
{ 
    OnStreamAvailable(students, httpContent, context); 
}, "text/plain"); 

到:

response.Content = new PushStreamContent((stream, httpContent, context) => 
{ 
    OnStreamAvailable(stream, httpContent, context); 
}, "text/plain"); 

爲什麼你不能使用students是因爲它已經被聲明爲前行的變量的原因:

var students = _symboleService.GetAll(); 
+0

我的觀點是流式傳輸所有學生的數據 – Juste3alfaz

+1

@ Juste3alfaz我的答案解釋了錯誤發生的原因。如果這不是你所問的,請更具體地說明你的問題。 – IronGeek

+0

對不起我的錯誤 – Juste3alfaz

2

這裏有幾個問題會阻礙你的進步。

首先,您的PushStreamContent構造函數中的Action不能重用變量名「students」。看起來你認爲你正在通過對Action的引用,但這不是這個工作方式。

你可以試試這個:

response.Content = new PushStreamContent(OnStreamAvailable, "text/plain"); 

但仍存在另一個問題。 PushStreamContent構造函數的操作中的流是一個輸出流。

public PushStreamContent(Action<Stream, HttpContent, TransportContext> onStreamAvailable); 

您會想要從您的OnStreamAvailable處理程序中寫入該流。

由於不清楚什麼是_symbolService.GetAll()方法,我只能推測從方法中生成的Byte []應該寫入到您的操作本身的輸出流中。

假設您的學生數據不是真正的流或固有流式,這可能是對PushStreamContent類的濫用。

+0

這是_symbolService.GetAll()方法的定義: public IQueryable GetAll() { var sortBy = SortBy.Ascending(「_ id」); MongoCursor cursor = _collection.FindAll()。SetSortOrder(sortBy); return cursor.AsQueryable (); } – Juste3alfaz

+1

然後原諒我給我的例子。這是不正確的。您可能正在討論將查詢轉換爲某種數組,然後對串行化數組進行流式處理,但我仍然不確定通過這種方式流式傳輸數據所要實現的目標。在整個流完成之前,這對消費者不會有用。 –

+0

對不起我的錯誤,我需要將數據推送給消費者,請參閱我的最新更新plz – Juste3alfaz