neuecc / AsyncOAuth

Portable Client Library and HttpClient based OAuth library, including all platform(for PCL).
101 stars 39 forks source link

Issue with Twitter Streaming #5

Open Ponf opened 11 years ago

Ponf commented 11 years ago

Hello, I have some problems with implementing streaming API:

First time I have created stream without setting timespan and it had worked. But some time after it stoped working: on creating stream I just receive friends id's and no tweets. Then I have tried to set timespan and get such error: "This instance has already started one or more requests. Properties can only be modified before sending the first request." but I set timespan after creating client and before any requests.

Thank you!

neuecc commented 11 years ago

Did you see SampleApp? https://github.com/neuecc/AsyncOAuth/blob/master/AsyncOAuth.ConsoleApp/Twitter.cs#L74

public async Task GetStream(Action<string> fetchAction)
{
    var client = OAuthUtility.CreateOAuthClient(consumerKey, consumerSecret, accessToken);
    client.Timeout = System.Threading.Timeout.InfiniteTimeSpan; // set infinite timespan

    using (var stream = await client.GetStreamAsync("https://userstream.twitter.com/1.1/user.json"))
    using (var sr = new StreamReader(stream))
    {
        while (!sr.EndOfStream)
        {
            var s = await sr.ReadLineAsync();
            fetchAction(s);
        }
    }
}

This code maybe work.

Ponf commented 11 years ago

Yes, I'm doing like in the sample:

    public void Init(TwitterToken token)
    {
        _client =
            new HttpClient(new OAuthMessageHandler(ConsumerKey, ConsumerSecret,
                                                   new AccessToken(token.AccessToken, token.TokenSecret)));
        _client.Timeout = Timeout.InfiniteTimeSpan;
    }

This is getting stream:

    public async void GetStream(Action<Tweet> timeLinecallback, Action<List<int>> friendsCallback)
    {
        const string url = "https://userstream.twitter.com/1.1/user.json";
        //   if (!_isFirstResponse)
        //  _client.Timeout = Timeout.InfiniteTimeSpan;
        using (var stream = await _client.GetStreamAsync(new Uri(url)))
        {
            using (var sr = new StreamReader(stream))
            {
                while (!sr.EndOfStream)
                {
                    var line = await sr.ReadLineAsync();
                    if (string.IsNullOrWhiteSpace(line))
                        return;

                    if (!_isFirstResponse)
                    {
                        var friendsResponse = JsonConvert.DeserializeObject<FriendsIdList>(line);
                        _isFirstResponse = true;
                        friendsCallback(friendsResponse.FriendsId);
                        return;
                    }
                    var tweet = JsonConvert.DeserializeObject<Tweet>(line);
                    timeLinecallback(tweet);
                }
            }
        }
    }

This is launching of stream:

        Task.Run(() => _client.GetStream(GetTweet, GetFriendsId));

and here are hadlers for friends and tweets:

    public void GetFriendsId(List<int> friendsId)
    {
        this.friendsId = friendsId;
    }

    public void GetTweet(Tweet tweet)
    {
        Execute.OnUIThread(() =>
        {
            if (tweet.entities != null && tweet.entities.user_mentions != null &&
                tweet.entities.user_mentions.Count != 0)
            {
                if (tweet.entities.user_mentions.Any(user => user.id.Equals(AccountId)))
                {
                    TimelineItemsCollection[1].Timeline.Insert(0, tweet);
                }
            }
            if (friendsId.Contains((int)tweet.user.id))
                TimelineItemsCollection[0].Timeline.Insert(0, tweet);
        });
    }

So I receive friends ID's, but don't receive tweets :(