2009-07-04 11 views
14

Próbuję użyć klas .NET WebRequest/WebResponse, aby uzyskać dostęp do interfejsu API przesyłania strumieniowego na Twitterze tutaj "http://stream.twitter.com/spritzer.json".Odczytywanie danych z otwartego strumienia HTTP

Muszę mieć możliwość otwierania połączenia i odczytu danych przyrostowo z otwartego połączenia.

Obecnie, gdy wywołuję metodę WebRequest.GetResponse, blokuje ona do momentu pobrania całej odpowiedzi. Wiem, że istnieje metoda BeginGetResponse, ale zrobi to samo na wątku tła. Muszę uzyskać dostęp do strumienia odpowiedzi, gdy pobieranie nadal trwa. Po prostu nie wydaje mi się to możliwe z tymi klasami.

Jest specyficzny komentarz na ten temat w dokumentacji Twitterze:

„Należy pamiętać, że niektóre biblioteki klienta HTTP tylko zwrócić treść odpowiedzi po połączenie zostało zamknięte przez serwer Tych klientów nie będzie działać dostępu. Interfejs API do przesyłania strumieniowego Należy użyć klienta HTTP, który będzie zwracał dane odpowiedzi stopniowo, na przykład większość odpornych bibliotek klienckich HTTP będzie zapewniać tę funkcjonalność, na przykład Apache HttpClient obsłuży ten przypadek użycia. "

Wskazują one na HttpClient Appache, ale to niewiele pomoże, ponieważ muszę używać .NET.

Wszelkie pomysły, czy jest to możliwe z WebRequest/WebResponse, czy też muszę przejść do niższych klas sieciowych? Może są inne biblioteki, które pozwolą mi to zrobić?

Thx Allen

Odpowiedz

0

Czy próbowałeś WebRequest.BeginGetRequestStream()?

Albo coś takiego:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create (http://www.twitter.com); 
HttpWebResponse response = (HttpWebResponse)request.GetResponse(); 
StreamReader reader = new StreamReader(response.GetResponseStream()); 

string str = reader.ReadLine(); 
while(str != null) 
{ 
    Console.WriteLine(str); 
    str = reader.ReadLine(); 
} 
+0

nie mogę używać WebRequest.BeginGetRequestStream bo nie próbuję zapisywać danych asynchronicznie na serwerze. Również w twoim przykładzie dzwonisz do GetResponse. Właśnie w tym momencie WebRequest blokuje się podczas pobierania odpowiedzi serwera. Ale połączenie nigdy się nie zamyka, ponieważ jest to nieskończony strumień danych. – user108687

-2

Wystarczy użyć WebClient. Jest przeznaczony do prostych przypadków, takich jak ten, w których nie potrzebujesz pełnej mocy WebRequest.

System.Net.WebClient wc = new System.Net.WebClient(); 
Console.WriteLine(wc.DownloadString("http://stream.twitter.com/spritzer.json")); 
+0

W jaki sposób klient sieci Web pozwala mi pobierać dane przyrostowe z otwartego połączenia strumieniowego HTTP? Wszystkie metody WebClient.Download * próbują pobrać całą odpowiedź. Muszę pobierać przyrostowe bloki nieskończonego strumienia danych HTTP. – user108687

+0

Och, potrzebujesz strumienia danych? Mój błąd. –

+0

Negatywny wynik ...Musisz przeczytać pytanie przed odpowiedzią :( –

13

skończyło się używając TcpClient, które działa prawidłowo. Nadal chciałbym wiedzieć, czy jest to możliwe dzięki WebRequest/WebResponse. Tu jest mój kodu w przypadku ktokolwiek jest zainteresowany:

using (TcpClient client = new TcpClient()) 
{ 

string requestString = "GET /spritzer.json HTTP/1.1\r\n"; 
requestString += "Authorization: " + token + "\r\n"; 
requestString += "Host: stream.twitter.com\r\n"; 
requestString += "Connection: keep-alive\r\n"; 
requestString += "\r\n"; 

client.Connect("stream.twitter.com", 80); 

using (NetworkStream stream = client.GetStream()) 
{ 
    // Send the request. 
    StreamWriter writer = new StreamWriter(stream); 
    writer.Write(requestString); 
    writer.Flush(); 

    // Process the response. 
    StreamReader rdr = new StreamReader(stream); 

    while (!rdr.EndOfStream) 
    { 
     Console.WriteLine(rdr.ReadLine()); 
    } 
} 
} 
+0

Czy konieczne jest \ r \ n? –

+4

Tak, HTTP jest protokołem zorientowanym na linie.Musisz rozdzielić polecenia przez \ r \ n. – Viet

+0

Czy strumień jest zwracany przez klienta. GetStream() faktycznie był przesyłany strumieniowo ze stosu sieciowego, czy jest to bufor pamięciowy? –

5

BeginGetResponse jest metoda trzeba. To pozwala na odczyt strumienia odpowiedzi stopniowo:

class Program 
{ 
    static void Main(string[] args) 
    { 
     WebRequest request = WebRequest.Create("http://stream.twitter.com/spritzer.json"); 
     request.Credentials = new NetworkCredential("username", "password"); 
     request.BeginGetResponse(ar => 
     { 
      var req = (WebRequest)ar.AsyncState; 
      // TODO: Add exception handling: EndGetResponse could throw 
      using (var response = req.EndGetResponse(ar)) 
      using (var reader = new StreamReader(response.GetResponseStream())) 
      { 
       // This loop goes as long as twitter is streaming 
       while (!reader.EndOfStream) 
       { 
        Console.WriteLine(reader.ReadLine()); 
       } 
      } 
     }, request); 

     // Press Enter to stop program 
     Console.ReadLine(); 
    } 
} 

Albo jeśli czujesz się bardziej komfortowo z WebClient (I personnally wolą go WebRequest):

using (var client = new WebClient()) 
{ 
    client.Credentials = new NetworkCredential("username", "password"); 
    client.OpenReadCompleted += (sender, e) => 
    { 
     using (var reader = new StreamReader(e.Result)) 
     { 
      while (!reader.EndOfStream) 
      { 
       Console.WriteLine(reader.ReadLine()); 
      } 
     } 
    }; 
    client.OpenReadAsync(new Uri("http://stream.twitter.com/spritzer.json")); 
} 
Console.ReadLine(); 
+0

Nie próbowałem tego, ponieważ założyłem, że polecenie req.EndGetResponse blokowałoby dokładnie ten sam sposób, co req.GetResponse, pozostawiając mnie z tym samym problemem I will give it shot – user108687

+0

Próbowałem tego bez powodzenia.Standard zwrócony przez .GetResponseStream() to MemoryStream zawierający całą zawartość odpowiedzi – Jeb

+0

@ Darin Dimitrov, Jak radzić sobie z timeoutami, jeśli są długie okresy między danymi przesyłanymi w strumieniu? –

Powiązane problemy