17

我正在尝试使用 .NET WebRequest/WebResponse 类在此处访问 Twitter 流 API "http://stream.twitter.com/spritzer.json"

我需要能够打开连接并从打开的连接中增量读取数据。

目前,当我调用WebRequest.GetResponse方法时,它会阻塞,直到下载整个响应。我知道有一种BeginGetResponse方法,但这只会在后台线程上做同样的事情。我需要在下载仍在进行时访问响应流。这些课程对我来说似乎是不可能的。

Twitter 文档中对此有具体评论:

“请注意,某些 HTTP 客户端库仅在服务器关闭连接后才返回响应正文。这些客户端将无法访问 Streaming API。您必须使用将逐步返回响应数据的 HTTP 客户端。最强大的 HTTP客户端库将提供此功能。例如,Apache HttpClient 将处理此用例。

他们指向 Appache HttpClient,但这并没有多大帮助,因为我需要使用 .NET。

任何想法是否可以使用WebRequest/WebResponse,或者我是否必须参加较低级别的网络课程?也许还有其他图书馆可以让我这样做?

谢谢艾伦

4

3 回答 3

17

我最终使用了一个 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());
        }
    }
}
于 2009-07-04T15:37:21.347 回答
13

BeginGetResponse is the method you need. It allows you to read the response stream incrementally:

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

Or if you feel more comfortable with WebClient (I personnally prefer it over 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();
于 2009-07-05T09:13:56.020 回答
0

您是否尝试过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();
}
于 2009-07-04T09:36:08.970 回答