我正在创建一个应用程序,其中 SignalR 用于将实时推文广播到地图。我正在使用 C# Tweetinvi 库 ( tweetinvi.codeplex.com ) 来处理与连接到 Twitter 流 API 相关的所有逻辑。
Twitter API 指定任何时候只能向 Twitter 打开一个流连接。当我使用 SignalR 时,流连接和 Hub 类之间存在依赖关系。我知道 Hub 类是瞬态的,这意味着每次客户端请求时都会创建它,因此我需要确保注入 Hub 类的 Twitter Stream 类的实例是单例的,或者至少IFilteredStream
只创建一次在应用程序的生命周期中。这是连接到 API 的样板代码:
public class TweetStream
{
private IFilteredStream _stream;
public TweetStream()
{
var consumerKey = ConfigurationManager.AppSettings.Get("twitter:ConsumerKey");
var consumerSecret = ConfigurationManager.AppSettings.Get("twitter:ConsumerSecret");
var accessKey = ConfigurationManager.AppSettings.Get("twitter:AccessKey");
var accessToken = ConfigurationManager.AppSettings.Get("twitter:AccessToken");
TwitterCredentials.SetCredentials(accessKey, accessToken, consumerKey, consumerSecret);
_stream = Stream.CreateFilteredStream();
}
// Return singular instance of _stream to Hub class for usage.
public IFilteredStream Instance
{
get { return _stream; }
}
}
IFilteredStream 接口公开了一个 lambda 方法,如下所示,它允许实时接收推文,我希望能够从我的 SignalR Hub 类中访问它:
_stream.MatchingTweetReceived += (sender, args) => {
Clients.All.broadcast(args.Tweet);
};
此方法的来源可以在这里找到
我尝试实现 Autofac,似乎与 Twitter API 的连接发生了,但没有发生任何其他事情。我试图调试这个,但我不确定如何使用依赖注入来调试这样的场景。我的 Hub 类目前如下所示:
public class TwitterHub : Hub
{
private readonly ILifetimeScope _scope;
private readonly TweetStream _stream;
// Inject lifetime scope and resolve reference to TweetStream
public TwitterHub(ILifetimeScope scope)
{
_scope = scope.BeginLifetimeScope();
_stream = scope.Resolve<TweetStream>();
var i = _stream.Instance;
_stream.MatchingTweetReceived += (sender, args) => {
Clients.All.broadcast(args.Tweet);
};
i.StartStreamMatchingAllConditions();
}
}
最后,我的 OWIN Startup 类,我在其中使用 Autofac 注册我的依赖项和集线器:
[assembly: OwinStartup(typeof(TwitterMap2015.App_Start.OwinStartup))]
namespace TwitterMap2015.App_Start
{
public class OwinStartup
{
public void Configuration(IAppBuilder app)
{
var builder = new ContainerBuilder();
// use hubconfig, not globalhost
var hubConfig = new HubConfiguration {EnableDetailedErrors = true};
builder.RegisterHubs(Assembly.GetExecutingAssembly()); // register all SignalR hubs
builder.Register(i => new TweetStream()).SingleInstance(); // is this the correct way of injecting a singleton instance of TweetStream?
var container = builder.Build();
hubConfig.Resolver = new AutofacDependencyResolver(container);
app.MapSignalR("/signalr", hubConfig);
}
}
}
抱歉,如果这个问题有点乱,我很难理解我需要实现什么样的架构才能让它工作!对如何改进或应该如何做的建议/建议持开放态度!