public class Startup { public void Configuration(IAppBuilder app) { var container = new AutofacContainer().Container; var resolver = new AutofacDependencyResolver(container); resolver.UseRedis("serverIp", portNumber, "password", "channelName"); app.UseAutofacMiddleware(container); app.MapSignalR(new HubConfiguration { Resolver = resolver }); resolver.UseRedis("192.168.122.213", 6300, "", "FLEDGG"); AddSignalRInjection(container, resolver); } private void AddSignalRInjection(IContainer container,IDependencyResolver resolver) { var updater = new ContainerBuilder(); updater.RegisterInstance(resolver.Resolve<IConnectionManager>()); updater.Update(container); } }
这是AutofacContainer类.
public class AutofacContainer { public IContainer Container { get; set; } public AutofacContainer() { var builder = new ContainerBuilder(); builder.RegisterHubs(Assembly.GetExecutingAssembly()) .PropertiesAutowired(); builder.RegisterType<Test>() .As<ITest>() .PropertiesAutowired(); Container = builder.Build(); } }
现在,the official SignalR Redis scaleout documentation from Microsoft声明我应该将GlobalHost.DependencyResolver告诉UseRedis.
public void Configuration(IAppBuilder app) { // Any connection or hub wire up and configuration should go here GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName"); app.MapSignalR(); }
由于我不再在应用程序中使用GlobalHost(即使我使用GlobalHost,Redis中绝对没有行为)(as the Autofac integration with SignalR and Owin indicates):
A common error in OWIN integration is use of the GlobalHost. In OWIN
you create the configuration from scratch. You should not reference
GlobalHost anywhere when using the OWIN integration.
由于现在配置了Startup类:
var resolver = new AutofacDependencyResolver(container); resolver.UseRedis("serverIp", portNumber, "password", "channelName");
所以我创建了一个AutofacDependencyResolver类型的新解析器,它成功连接到Redis PubSub.但问题是,如果我尝试发送单个消息,该消息将重复数千次.
(在Chrome控制台中,为了从服务器发送单个消息,我最终处于无限循环中,客户端无限次地接收它).
因此,问题是:当使用Autofac作为依赖性解析器时,如何设置SignalR Redis scaleout(注意:没有可以使用其他依赖性resover的情况).
谢谢!
编辑:如果您想了解有关该解决方案的更多信息,请联系here is the repo:
resolver.UseRedis("serverIp", portNumber, "password", "channelName");
谢谢!
编辑:我觉得我应该澄清一些事情:如果我使用resolver.UseRedis();,每次正常发送的消息(一次)都会多次发送 – 所以如果我使用订阅“channelName”订阅Redis中的“channelName” “,我发现它与客户端上的行为一致:每条消息都会多次发送.
接下来要做的是拥有一个没有Autofac的基本SignalR应用程序,看看Redis的行为,尽管我觉得这是一个与Autofac相关的问题,更具体地说与配置有关.
谢谢!
更新:显然,没有Autofac的基本SignalR应用程序中存在相同的行为.这个问题与Autofac无关.
好的,我发现了发生了什么:我使用的Redis服务器配置为在群集中一起运行多个实例.
默认情况下,如果您有Redis群集并在任何实例上的通道上发布消息,则默认情况下将在所有其他实例上转发该消息.
In a Redis Cluster clients can subscribe to every node, and can also
publish to every other node. The cluster will make sure that published
messages are forwarded as needed. The current implementation will
simply broadcast each published message to all other nodes.
The Redis cluster specification.
最有可能的是,SignalR实现被配置为接收来自Redis的任何消息,因此我的行为很奇怪.
解决方案是让Redis实例不在集群中,一切正常.
如果您想拥有SignalR背板,请不要使用群集中的实例!