我有以下情况:我有一个SignalR应用程序,我在其中使用Autofac作为依赖项解析器。
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):
OWIN集成中的常见错误是使用GlobalHost。在OWIN 您从头开始创建配置。你不应该参考 使用OWIN集成时GlobalHost。
由于现在配置了Startup
类:
var resolver = new AutofacDependencyResolver(container);
resolver.UseRedis("serverIp", portNumber, "password", "channelName");
所以我创建了一个类型为resolver
的新AutofacDependencyResolver
,它成功连接到Redis PubSub。但问题是,如果我尝试发送单个消息,该消息将重复数千次。
(在Chrome控制台中,为了从服务器发送单个消息,我最终无限循环,客户端无限次地接收它。)
所以,问题是:当使用Autofac作为依赖性解析器时,如何设置SignalR Redis scaleout(注意:没有可以使用其他依赖性resover的情况)。
谢谢!
编辑:如果您想了解有关解决方案的更多信息,here is the repo没有此行:
resolver.UseRedis("serverIp", portNumber, "password", "channelName");
谢谢!
编辑:我觉得我应该澄清一些事情:如果我使用resolver.UseRedis();
,那么通常发送的每条消息(一次)都会多次发送 - 所以如果我使用{订阅Redis中的“channelName” {1}},我发现它与客户端上的行为一致:每条消息都会多次发送。
接下来要做的是拥有一个没有Autofac的基本SignalR应用程序,看看Redis的行为如何,虽然我觉得这是一个与Autofac相关的问题,更具体地说与配置有关。
谢谢!
更新:显然,没有Autofac的基本SignalR应用程序中存在相同的行为。这个问题与Autofac无关。
答案 0 :(得分:1)
好的,我发现了发生了什么:
我正在使用的Redis服务器配置为在群集中一起运行多个实例。
默认情况下,如果您有Redis群集并在任何实例上的通道上发布消息,则默认情况下将在所有其他实例上转发该消息。
在Redis群集中,客户端可以订阅每个节点,也可以 发布到每个其他节点。群集将确保已发布 根据需要转发消息。目前的实施将 只需将每个已发布的消息广播到所有其他节点。
The Redis cluster specification.
最有可能的是,SignalR实现被配置为接收来自Redis的任何消息,因此我的行为很奇怪。
解决方案是让Redis实例不在群集中,一切正常。
如果您想拥有SignalR背板,请不要使用群集中的实例!