使用C#从Twitter Stream API发出401错误

时间:2013-06-26 16:07:08

标签: c# api twitter stream http-status-code-401

当我尝试将其转换为流API时,我得到401:“https://stream.twitter.com/1/statuses/filter.json”。我真的很感激任何帮助。见下面的代码:

            HttpWebRequest request = null;

            string oauth_consumer_key = "XXXXXXXXXXXXX";
            string oauth_consumer_secret = "XXXXXXXXXXXXXXXX";
            string oauth_token = "XXXXXXXXXXXXXXXXXXXXX";
            string oauth_token_secret = "XXXXXXXXXXXXXXXXXXXXXXXXX";
            string oauth_version = "1.0";
            string oauth_signature_method = "HMAC-SHA1";
            string oauth_nonce = Convert.ToBase64String(new ASCIIEncoding().GetBytes(DateTime.Now.Ticks.ToString()));
            TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
            string oauth_timestamp = Convert.ToInt64(timeSpan.TotalSeconds).ToString();

            Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");

            int backOff = 250;
            string line = string.Empty;

            try
            {
                string parameters = this.GetQuery(template);

                string baseFormat = "oauth_consumer_key={0}&oauth_nonce={1}&oauth_signature_method={2}" +
                                     "&oauth_timestamp={3}&oauth_token={4}&oauth_version={5}";
                                     &track={6}"
                string baseString = string.Format(baseFormat,
                                                    oauth_consumer_key,
                                                    oauth_nonce,
                                                    oauth_signature_method,
                                                    oauth_timestamp,
                                                    oauth_token,
                                                    oauth_version,
                                                    Uri.EscapeDataString(parameters)
                                                    );

                baseString = string.Concat("POST&", Uri.EscapeDataString(this.Datasource), "&", Uri.EscapeDataString(baseString));

                string compositeKey = string.Concat(Uri.EscapeDataString(oauth_consumer_secret), "&", Uri.EscapeDataString(oauth_token_secret));

                string oauth_signature;
                using (HMACSHA1 hasher = new HMACSHA1(ASCIIEncoding.ASCII.GetBytes(compositeKey)))
                {
                    oauth_signature = Convert.ToBase64String(
                    hasher.ComputeHash(ASCIIEncoding.ASCII.GetBytes(baseString)));
                }

                // create the request header
                string headerFormat = "OAuth oauth_consumer_key=\"{0}\", oauth_nonce=\"{1}\", " + 
                                      "oauth_signature=\"{2}\", oauth_signature_method=\"{3}\", " +
                                      "oauth_timestamp=\"{4}\",  " +
                                      "oauth_token=\"{5}\", " +
                                      "oauth_version=\"{6}\"";

                string authHeader = string.Format(headerFormat,
                                                Uri.EscapeDataString(oauth_consumer_key),
                                                Uri.EscapeDataString(oauth_nonce),
                                                Uri.EscapeDataString(oauth_signature),
                                                Uri.EscapeDataString(oauth_signature_method),
                                                Uri.EscapeDataString(oauth_timestamp),
                                                Uri.EscapeDataString(oauth_token),
                                                Uri.EscapeDataString(oauth_version)
                                                );

                ServicePointManager.Expect100Continue = false;
                //string postBody = string.Format("track={0}", parameters);
                string postBody = "track=" + Uri.EscapeDataString(parameters);

                request = (HttpWebRequest)WebRequest.Create(this.Datasource + "?" + postBody);
                request.Headers.Add("Authorization", authHeader);
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.PreAuthenticate = true;
                request.AllowWriteStreamBuffering = true;

                using (WebResponse response = request.GetResponse())
                {
                   using (StreamReader reader = new StreamReader(response.GetResponseStream()))
                    {
                        string responseData = new StreamReader(response.GetResponseStream()).ReadToEnd();

                        //we successfully connected so reset the twitter backoff time

            }
            catch (WebException wex)
            {
                if (wex.Status == WebExceptionStatus.ProtocolError)
                {
                    /* as per twitter api
                     * 
                     * When a HTTP error (> 200) is returned, back off exponentially.  
                     * Perhaps start with a 10 second wait, double on each subsequent failure,
                     * and finally cap the wait at 240 seconds. 
                     * 
                     * Exponential Backoff
                     */
                    if (backOff < TwitterStreamProvider.InitialExponentialBackOff)
                    {
                        backOff = TwitterStreamProvider.InitialExponentialBackOff;
                    }
                    else
                    {
                        if (backOff < TwitterStreamProvider.MaxExponentialBackOff)
                        {
                            backOff *= TwitterStreamProvider.ExponentialBackOff;
                        }
                    }
                }
                else
                {
                    /* as per twitter api
                     * 
                     * When a network error (TCP/IP level) is encountered, back off linearly.  
                     * Perhaps start at 250 milliseconds and cap at 16 seconds.
                     * 
                     * Linear Backoff
                     */
                    if (backOff < TwitterStreamProvider.MaxLinearBackOff)
                    {
                        backOff += TwitterStreamProvider.LinearBackOff;
                    }
                }

                Logger.Error(
                    string.Format("There was a problem trying to connect to the twitter stream.  Will try to establish connection again in {0} milliseconds",
                        backOff),
                    wex);
            }
            catch (OperationCanceledException cex)
            {
                Logger.Error("Twitter stream thread was canceled", cex);
                cancelled = true;
            }
            catch (Exception ex)
            {
                Logger.Error("There was a problem while scraping twitter.", ex);
                Logger.Debug(string.Format("Last tweet before the error: {0}", line));
                throw;
            }
            finally
            {
                if (request != null)
                {
                    request.Abort();
                    request = null;
                }
            }

            if (!cancelled)
            {
                System.Threading.Thread.Sleep(backOff);
            }
        }
    }

/

请你指出我做错了什么。

谢谢, 玛尔塔

2 个答案:

答案 0 :(得分:0)

我认为这个问题可能会帮助你(同样的错误信息):Getting 401 from Twitter Stream API using C#

答案 1 :(得分:0)

我尝试使用你的代码,但没有完整的类,并且知道什么是this.DataSource和this.GetQuery()似乎很难帮助你。

让我建议使用像Tweetinvi这样的外部Twitter流媒体API,它拥有一个名为Streaminvi的项目,该项目有FilteredStream类,可以为您完成这项工作。

以下是如何使用它:

FilteredStream stream = new FilteredStream();
// Create a Token to access Twitter
IToken token = new Token("userKey", "userSecret", "consumerKey", "consumerSecret");
// Adding Tracks filters
stream.AddTrack("HelloMartha");
stream.AddTrack("TrackNumber2!");
// Write the Text of each Tweet in the Console
stream.StartStream(token, x => Console.WriteLine(x.Text));

完成:)