3

そのため、Signalr を Twitter ストリーミング API で使用しようとしています。具体的には、Tweetinvi C# API ( http://tweetinvi.codeplex.com/ ) を使用しています。

アプリの目的は、特定のキーワードでフィルター処理されたツイートをリアルタイムでページにストリーミングすることです。

TweetInvi ライブラリはうまく機能し、特定のキーワードを含むツイートをコマンド ライン アプリケーションで正常に出力できます。

私の使い方の基本的な概要は次のとおりです。

テキスト入力とボタン (フィルターを更新するため) を備えた単一のページを備えた MVC Web アプリがあり、Signalr Hub の Hub メソッドを呼び出して、ストリームがまだ存在しない場合はストリームを開始し、停止します。 2 回目のボタン クリック。

シグナル部分を除いて、これはすべて正常に機能しています。

public class TweetHub : Hub
{
    private IStreamManager _streamManager;

    public void AddTweet(String tweet, double lat, double lon)
    {
        Clients.All.addTweet(tweet, lat, lon);
    }

    public void StartStream(String[] filters)
    {
        string accessToken = ConfigurationManager.AppSettings["AccessToken"];
        string accessTokenSecret = ConfigurationManager.AppSettings["AccessTokenSecret"];
        string consumerKey = ConfigurationManager.AppSettings["ConsumerKey"];
        string consumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"];

        IToken token = new Token(accessToken, accessTokenSecret, consumerKey, consumerSecret);

        if (_streamManager != null && _streamManager.StreamIsOpen())
        {
            _streamManager.StopStream();
            _streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
        }
        else if (_streamManager != null && !_streamManager.StreamIsOpen())
        {
            _streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
        }
        else
        {
            _streamManager = new StreamManager();
            _streamManager.StartStream(token, filters, tweet => AddTweet(tweet.Text, tweet.LocationCoordinates.Lattitude, tweet.LocationCoordinates.Longitude));
        }
    }

    public void StopStream()
    {
        if (_streamManager != null && _streamManager.StreamIsOpen())
        {
            _streamManager.StopStream();
        }
    }
}

これが Signalr Hub のコードです。先ほど言ったように、js を使用すると、ストリーム メソッドの開始と停止を正常にトリガーできます。

これは私の StreamManager クラスのコードです:

public class StreamManager : IStreamManager
{
    private StreamClient _streamClient;
    private bool _streamOpen = false;

    public void StartStream(IToken token, String[] filters, Action<ITweet> action)
    {
        if (_streamClient == null)
            _streamClient = new StreamClient(token, filters, new FilteredStream());

        _streamClient.StartStream(action);
        _streamOpen = true;
    }

    public void StopStream()
    {
        if (_streamClient != null)
        {
            _streamClient.StopStream();
            _streamOpen = false;
        }
    }

    public bool StreamIsOpen()
    {
        return _streamOpen;
    }

    public void Dispose()
    {
        if (_streamOpen)
        {
            StopStream();
        }
        _streamClient.Dispose();
        _streamClient = null;
    }
}

私の StreamClient クラスのコード:

public class StreamClient : IStreamClient
{
    private IFilteredStream _filteredStream;
    private IToken _token;
    private bool _streamOpen = false;


    public StreamClient(IToken token, String[] filters, IFilteredStream filteredStream)
    {
        _token = token;
        _filteredStream = filteredStream;
        AddFilters(filters);
    }

    private void AddFilters(String[] filters)
    {
        for (int i = 0; i < filters.Length; ++i)
        {
            _filteredStream.AddTrack(filters[i]);
        }
    }

    public void StartStream(Action<ITweet> action)
    {
        _filteredStream.StartStream(_token, action);
        _streamOpen = true;

    }

    public void StartStream(Func<ITweet, bool> predicateFunc)
    {
        _filteredStream.StartStream(_token, predicateFunc);
        _streamOpen = true;
    }

    public void StopStream()
    {
        _filteredStream.StopStream();
        _streamOpen = false;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            // free managed resources
            if (_streamOpen)
            {
                _filteredStream.StopStream();
                _filteredStream = null;
                _token = null;
            }
        }
    }

上記のコードは、Tweetinvi ライブラリを直接呼び出す場所です。

私の問題は、Hub メソッドを StreamManager の StartStream メソッドに Action パラメーターとして渡すと、AddTweet メソッドがヒットしないことです。

前述したように、代わりにコマンド プロンプト アプリケーションをクライアントとして使用し、次のコードを使用すると、これはすべて正常に機能します。

static void Main(string[] args)
{

    string accessToken = ConfigurationManager.AppSettings["AccessToken"];
    string accessTokenSecret = ConfigurationManager.AppSettings["AccessTokenSecret"];
    string consumerKey = ConfigurationManager.AppSettings["ConsumerKey"];
    string consumerSecret = ConfigurationManager.AppSettings["ConsumerSecret"];


    IToken token = new Token(accessToken, accessTokenSecret, consumerKey, consumerSecret);

    String[] filters = new string[2]
    {
            "test",
            "twitter"
    };

    StreamClient streamClient = new StreamClient(token, filters, new FilteredStream());
        streamClient.StartStream(tweet => TestMethod());
}

public static void TestMethod()
{
    Console.WriteLine("test");
}

これは完全に機能し、受信したキーワードを含むツイートを出力します。

これは、ストリームが確実に開かれるため、Signalr の使用方法に問題があり、signaler メソッドがヒットしないことを信じさせてくれます。ハブと私がそれを使用している方法。

これは、ハブの StartStream メソッドが正常に呼び出され、クリックされたボタンが更新されますが、もう一度クリックして StopStream を呼び出すと思うと、StopStream メソッドがヒットしますが、「_streamManager」メンバー変数が null であるためと思われます。ハブが存続期間中に状態を維持する場合は、すべきではありませんが、そうではないと思います。

それかそれが処分されているかのどちらかであり、ストリームはとにかく存在しません。

Signalr を適切にデバッグするのに十分な経験がありません。

助けてくれてありがとう。

4

1 に答える 1