Чтение данных из открытого HTTP-потока
Я пытаюсь использовать классы .NET WebRequest/WebResponse для доступа к API потоковой передачи Twitter здесь "http://stream.twitter.com/spritzer.json"
.
Мне нужно иметь возможность открывать соединение и читать данные постепенно из открытого соединения.
В настоящее время, когда я вызываю метод WebRequest.GetResponse
, он блокируется до тех пор, пока не будет загружен весь ответ. Я знаю, что существует метод BeginGetResponse
, но это будет делать то же самое в фоновом потоке. Мне нужно получить доступ к потоку ответов во время загрузки. Мне это не кажется возможным с этими классами.
В документации Twitter есть специальный комментарий:
"Обратите внимание, что некоторые клиентские библиотеки HTTP возвращают тело ответа только после того, как соединение было закрыто сервером. Эти клиенты не будут работать для доступа к Streaming API. Вы должны использовать HTTP-клиент, который будет возвращать данные ответа постепенно. Большинство надежных клиентских библиотек HTTP предоставят эту функцию. Например, Apache HttpClient будет обрабатывать этот вариант использования."
Они указывают на Appache HttpClient, но это мало помогает, потому что мне нужно использовать .NET.
Любые идеи, возможно ли это с помощью WebRequest/WebResponse
, или мне нужно идти на сетевые классы более низкого уровня? Может быть, есть другие библиотеки, которые позволят мне это сделать?
спасибо
Аллен
Ответы
Ответ 1
В итоге я использовал TcpClient, который отлично работает. Было бы интересно узнать, возможно ли это с помощью WebRequest/WebResponse. Вот мой код на тот случай, если кто-то заинтересован:
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());
}
}
}
Ответ 2
BeginGetResponse - это тот метод, который вам нужен. Он позволяет вам постепенно считывать поток ответов:
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();
}
}
Или, если вам комфортно с WebClient (я лично предпочитаю его над 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();
Ответ 3
Вы пробовали WebRequest.BeginGetRequestStream()?
Или что-то вроде этого:
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();
}
Ответ 4
Просто используйте WebClient
. Он предназначен для таких простых случаев, когда вам не нужна полная мощность WebRequest.
System.Net.WebClient wc = new System.Net.WebClient();
Console.WriteLine(wc.DownloadString("http://stream.twitter.com/spritzer.json"));