2009-07-04 15 views
14

Estoy tratando de utilizar las clases .NET WebRequest/WebResponse para acceder a la API de transmisión de Twitter aquí "http://stream.twitter.com/spritzer.json".Lectura de datos de una secuencia HTTP abierta

Necesito poder abrir la conexión y leer datos de forma incremental desde la conexión abierta.

Actualmente, cuando llamo al método WebRequest.GetResponse, bloquea hasta que se descarga la respuesta completa. Sé que hay un método BeginGetResponse, pero esto solo hará lo mismo en un hilo de fondo. Necesito tener acceso a la secuencia de respuesta mientras la descarga continúa. Esto simplemente no me parece posible con estas clases.

Hay un comentario específico sobre esto en la documentación Twitter:

"Tenga en cuenta que algunas bibliotecas de cliente HTTP sólo devuelven el cuerpo de la respuesta después de la conexión ha sido cerrada por el servidor Estos clientes no funcionarán para el acceso. Streaming API. Debe usar un cliente HTTP que devolverá datos de respuesta de forma incremental. La mayoría de las sólidas bibliotecas de clientes HTTP proporcionarán esta funcionalidad. El Apache HttpClient manejará este caso de uso, por ejemplo.

Señalan Appache HttpClient, pero eso no ayuda mucho porque necesito usar .NET.

¿Alguna idea si esto es posible con WebRequest/WebResponse, o tengo que ir para las clases de redes de nivel inferior? ¿Tal vez haya otras bibliotecas que me permitan hacer esto?

Thx Allen

Respuesta

0

¿Usted ha intentado WebRequest.BeginGetRequestStream()?

O algo así:

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

no puedo usar porque WebRequest.BeginGetRequestStream no estoy intentando escribir datos de manera asincrónica en el servidor. Además, en su ejemplo, llama a GetResponse. Es en este punto que WebRequest está bloqueando mientras descarga la respuesta del servidor. Pero la conexión nunca se cierra porque es una corriente de datos interminable. – user108687

-2

sólo tiene que utilizar WebClient. Está diseñado para casos simples como este donde no necesita todo el poder de WebRequest.

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

¿Cómo exactamente me permite el cliente web tomar datos incrementales de una conexión HTTP de transmisión abierta? Todos los métodos de WebClient.Download * intentan descargar toda la respuesta. Necesito tomar bloques incrementales de una secuencia interminable de datos HTTP. – user108687

+0

Oh, necesitas transmitir datos? Mi error. –

+0

Puntuación negativa ...Debe leer la pregunta antes de responderla :( –

13

Terminé utilizando un TcpClient, que funciona bien. Sin embargo, todavía estaría interesado en saber si esto es posible con WebRequest/WebResponse. Aquí está mi código en caso de que alguien está interesado:

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

¿Es necesario '\ r \ n'? –

+4

Sí, HTTP es un protocolo orientado a la línea. Debe separar los comandos por \ r \ n. – Viet

+0

Es la secuencia devuelta por el cliente. GetStream() realmente transmitido desde la pila de la red o solo es una secuencia de memoria almacenada en caché? –

5

BeginGetResponse es el método que necesita. Se le permite leer la secuencia de respuesta incremental:

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

O si se siente más cómodo con WebClient (I personalmente prefiere sobre 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

No probé esto porque supuse que la req.EndGetResponse se bloquearía exactamente de la misma forma que lo hace ReG.Respuesta, dejándome con el mismo problema Voy a intentarlo. – user108687

+0

Lo intenté sin suerte. La transmisión devuelta por .GetResponseStream() es un MemoryStream que contiene todo el contenido de la respuesta. – Jeb

+0

@Darin Dimitrov, ¿Cómo se manejan los tiempos de espera si son largos? períodos de tiempo entre los datos que llegan a través de la secuencia? –

Cuestiones relacionadas