2009-07-04 20 views
14

Ich versuche, die .NET WebRequest/WebResponse-Klassen zu verwenden, um auf die Twitter-Streaming-API hier "http://stream.twitter.com/spritzer.json" zuzugreifen.Lesen von Daten aus einem offenen HTTP-Stream

Ich muss in der Lage sein, die Verbindung zu öffnen und Daten inkrementell von der offenen Verbindung zu lesen.

Derzeit, wenn ich WebRequest.GetResponse Methode aufrufen, blockiert es, bis die gesamte Antwort heruntergeladen wird. Ich weiß, dass es eine BeginGetResponse Methode gibt, aber das wird nur die gleiche Sache auf einem Hintergrundthread tun. Ich muss Zugriff auf den Antwortstream erhalten, während der Download noch stattfindet. Das scheint mir mit diesen Klassen nicht möglich zu sein.

Es gibt einen bestimmten Kommentar dazu in der Twitter-Dokumentation:

„Bitte beachten Sie, dass einige HTTP-Client-Bibliotheken nur die Antwort Körper zurückkehren, nachdem die Verbindung vom Server geschlossen wurde Diese Clients funktionieren nicht für den Zugriff. Die Streaming-API. Sie müssen einen HTTP-Client verwenden, der Antwortdaten inkrementell zurückgibt. Die meisten robusten HTTP-Clientbibliotheken bieten diese Funktionalität. Der Apache HttpClient wird beispielsweise diesen Anwendungsfall behandeln. "

Sie verweisen auf den Appache HttpClient, aber das hilft nicht viel, weil ich .NET verwenden muss.

Irgendwelche Ideen, ob dies mit WebRequest/WebResponse möglich ist, oder muss ich für niedrigere Netzwerkklassen gehen? Vielleicht gibt es andere Bibliotheken, die mir erlauben, dies zu tun?

Thx Alle

Antwort

0

Haben Sie versucht WebRequest.BeginGetRequestStream()?

Oder etwas Ähnliches:

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

Ich kann nicht WebRequest.BeginGetRequestStream weil ich Ich versuche nicht, Daten asynchron zum Server zu schreiben. In Ihrem Beispiel rufen Sie GetResponse auf. An diesem Punkt blockiert die WebRequest, während sie die Serverantwort herunterlädt. Die Verbindung wird jedoch nie geschlossen, da es sich um einen praktisch endlosen Datenstrom handelt. – user108687

-2

Nur WebClient verwenden. Es ist für einfache Fälle wie diesen konzipiert, in denen Sie nicht die volle Leistung von WebRequest benötigen.

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

Wie genau ermöglicht es mir der Web-Client, inkrementelle Daten von einer offenen Streaming-HTTP-Verbindung zu empfangen? Alle WebClient.Download * -Methoden versuchen, die gesamte Antwort herunterzuladen. Ich muss inkrementelle Blöcke eines endlosen Stroms von HTTP-Daten nehmen. – user108687

+0

Oh, Sie müssen Daten streamen? Mein Fehler. –

+0

Negative Punktzahl ...Sie müssen die Frage lesen, bevor Sie sie beantworten :( –

13

Ich endete mit einem TcpClient, der gut funktioniert. Wäre dennoch interessant zu wissen, ob dies mit WebRequest/WebResponse möglich ist. Hier ist mein Code, falls jemand interessiert:

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

Ist das '\ r \ n' notwendig? –

+4

Ja, HTTP ist ein leitungsorientiertes Protokoll. Sie müssen die Befehle nach \ r \ n trennen. – Viet

+0

Wird der Stream vom Client zurückgegeben? GetStream() tatsächlich aus dem Netzwerk-Stack gestreamt oder ist es nur ein Cache-Speicher-Stream? –

5

BeginGetResponse die Methode, die Sie benötigen. Es ermöglicht Ihnen die Antwort Stream zu lesen inkrementell:

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(); 
    } 
} 

Oder wenn Sie fühlen sich wohler mit WebClient (ich ziehe persönlich es über 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

Ich habe dies nicht versucht, weil ich annahm, die req.EndGetResponse würde in genau der gleichen Weise blockieren req.GetResponse tut, so dass ich mit dem gleichen Problem Ich gebe es eine Chance. – user108687

+0

Ich versuchte dies ohne Glück. Der von. GetResponseStream() zurückgegebene Stream ist ein MemoryStream, der den gesamten Inhalt der Antwort enthält. – Jeb

+0

@Darin Dimitrov, Wie gehen Sie mit Timeouts um, wenn es lang ist Zeiträume zwischen Daten, die auf dem Strom durchkommen? –