そのため、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 を適切にデバッグするのに十分な経験がありません。
助けてくれてありがとう。