Quantcast
Channel: Tweetinvi a friendly Twitter C# library
Viewing all articles
Browse latest Browse all 4126

New Post: Is it possible to add more tracks to a running stream instead of creating a new one?

$
0
0
Many Thanks ,

I just need to share this work with you and other guys, I just wanted that the stream to listen to any upcoming requests for adding new tracks to it
without breaking your design, so I have made the following modifications in the following classes:

In the TrackedStream base class I have added the following property
public BlockingCollection<Dictionary<int, string>> MoreTracks { get; set; } 
it is a blocking collection for new keywords that should be based to StreamResultGenerator's StartStream method by FilteredStream's StartStreamMatchingAnyCondion method to be observed there:
public void StartStreamMatchingAnyCondition()
        {
            Func<HttpWebRequest> generateWebRequest = () => _oAuthToken.GetQueryWebRequest(GenerateORFilterQuery(), HttpMethod.POST);

            Action<string> tweetReceived = json =>
            {
                var tweet = _tweetFactory.GenerateTweetFromJson(json);
                if (tweet == null)
                {
                    TryInvokeGlobalStreamMessages(json);
                    return;
                }

                var matchingTrackAndActions = _streamTrackManager.GetMatchingTracksAndActions(tweet.Text);
                var matchingTracks = matchingTrackAndActions.Select(x => x.Item1);
                var machingLocationAndActions = GetMatchedLocations(tweet.Coordinates);
                var matchingLocations = machingLocationAndActions.Select(x => x.Key);

                CallMultipleActions(tweet, matchingTrackAndActions.Select(x => x.Item2));
                CallMultipleActions(tweet, machingLocationAndActions.Select(x => x.Value));
                CallFollowerAction(tweet);

                RaiseMatchingTweetReceived(new MatchedTweetReceivedEventArgs(tweet, matchingTracks));
                this.Raise(MatchingTweetAndLocationReceived, new MatchedTweetAndLocationReceivedEventArgs(tweet, matchingTracks, matchingLocations));
            };

            if (MoreTracks != null)
                _streamResultGenerator.StartStream(tweetReceived, generateWebRequest, MoreTracks);

            _streamResultGenerator.StartStream(tweetReceived, generateWebRequest);
        } 
it's an overload for the StartStream method and here's the implementation:
public void StartStream(Func<string, bool> processObject, Func<HttpWebRequest> generateWebRequest, BlockingCollection<Dictionary<int, string>> moreTracks)
        {
            if (IsRunning)
            {
                throw new OperationCanceledException(Resources.Stream_IllegalMultipleStreams);
            }

            if (processObject == null)
            {
                throw new NullReferenceException(Resources.Stream_ObjectDelegateIsNull);
            }

            _lastException = null;
            _streamState = StreamState.Resume;
            this.Raise(StreamStarted);

            HttpWebRequest webRequest = generateWebRequest();
            _currentReader = InitWebRequest(webRequest);

            if (_lastException != null)
            {
                _streamState = StreamState.Stop;
            }

            int errorOccured = 0;
            while (StreamState != StreamState.Stop)
            {
                if (StreamState == StreamState.Pause)
                {
                    Thread.Sleep(STREAM_RESUME_DELAY);
                    continue;
                }

                try
                {
                    if (moreTracks.Count > 0)
                    {
                        StopStream(moreTracks.Take());
                        break;
                    }
                        
                    string jsonResponse = _currentReader.ReadLine();

                    #region Error Checking

                    if (jsonResponse == null)
                    {
                        if (errorOccured == 0)
                        {
                            ++errorOccured;
                        }
                        else if (errorOccured == 1)
                        {
                            ++errorOccured;
                            webRequest.Abort();
                            _currentReader = InitWebRequest(webRequest);
                        }
                        else if (errorOccured == 2)
                        {
                            ++errorOccured;
                            webRequest.Abort();
                            webRequest = generateWebRequest();
                            _currentReader = InitWebRequest(webRequest);
                        }
                        else
                        {
                            Trace.WriteLine("Twitter API is not accessible");
                            break;
                        }
                    }
                    else
                    {
                        errorOccured = 0;
                    }

                    #endregion

                    if (jsonResponse == String.Empty)
                    {
                        continue;
                    }

                    if (StreamState == StreamState.Resume && !processObject(jsonResponse))
                    {
                        StreamState = StreamState.Stop;
                        break;
                    }
                }
                catch (WebException wex)
                {
                    _exceptionHandler.AddWebException(wex, String.Empty);
                }
                catch (Exception ex)
                {
                    _lastException = ex;

                    if (ex is IOException)
                    {
                        if (StreamState == StreamState.Stop)
                        {
                            return;
                        }

                        if (ex.Message == "Unable to read data from the transport connection: The connection was closed.")
                        {
                            _currentReader = InitWebRequest(webRequest);
                        }

                        try
                        {
                            _currentReader.ReadLine();
                            _lastException = null;
                        }
                        catch (IOException ex2)
                        {
                            if (ex2.Message == "Unable to read data from the transport connection: The connection was closed.")
                            {
                                Trace.WriteLine("Streamreader was unable to read from the stream!");
                            }
                        }
                        catch (ObjectDisposedException)
                        {
                            // StopStream has been called
                            _lastException = null;
                        }
                    }

                    break;
                }
            }

            if (webRequest != null)
            {
                webRequest.Abort();
            }

            if (_currentReader != null)
            {
                _currentReader.Dispose();
            }

            StreamState = StreamState.Stop;
        }
if more tracks need to be added and passed by the implementing methods it will stop the stream and passing the new keywords back as arguments for StreamStoppedEvent to decide to start the stream again with the new keywords.
public void StopStream(Dictionary<int, string> moreTracks)
        {
            _lastException = null;
            _streamState = StreamState.Stop;
            var streamExceptionEventArgs = new StreamExceptionEventArgs(moreTracks);
            this.Raise(StreamStopped, streamExceptionEventArgs);
        }
stream.StreamStopped += (sender, args) =>
            {

                // If new keywords need to be added to stream then add them and restart this stream
                if (args.NewTracksToAdd != null)
                {
                    //_logger.Log(logPath, LogType.Normal, Thread.CurrentThread.ManagedThreadId.ToString(), "SocialTrackerAgent", "UpdateStream", _params, "Void", string.Join(",", args.NewTracksToAdd));

                    args.NewTracksToAdd.Foreach(current =>
                    {
                        stream.AddTrack(current.Value);
                        handler.ExecuteNonQueryEx("Update KEYWORDS set FOLLOWING=1 where ID=" + current.Key);
                       // ProcObj.ExecuteNonQuerySqlString("Update KEYWORDS set FOLLOWING=1 where ID=" + current.Key, "orcl", "socialtracker", "socialtracker");
                    }
                      );

                }

                else
                {
                    lock (_lockObj)
                    {
                        //_params.Add("SenderStream", _stream.ToString());
                        _logger.Log(logPath, LogType.Exception, Thread.CurrentThread.ManagedThreadId.ToString(), "SocialTrackerAgent", "StreamStopped", _params, "Void", args.Exception.ToString());
                    }
                }


                // Pause This Stream for 2 seconds
                Thread.Sleep(2 * 1000);
                stream.StartStreamMatchingAllConditions();
            };

Viewing all articles
Browse latest Browse all 4126

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>