SignalR& Autofac - Redis背板向外扩展

时间:2015-09-17 08:49:09

标签: dependency-injection redis signalr autofac signalr-backplane

我有以下情况:我有一个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无关。

1 个答案:

答案 0 :(得分:1)

好的,我发现了发生了什么:

我正在使用的Redis服务器配置为在群集中一起运行多个实例。

默认情况下,如果您有Redis群集并在任何实例上的通道上发布消息,则默认情况下将在所有其他实例上转发该消息。

  

在Redis群集中,客户端可以订阅每个节点,也可以   发布到每个其他节点。群集将确保已发布   根据需要转发消息。目前的实施将   只需将每个已发布的消息广播到所有其他节点。

The Redis cluster specification.

最有可能的是,SignalR实现被配置为接收来自Redis的任何消息,因此我的行为很奇怪。

解决方案是让Redis实例不在群集中,一切正常。

如果您想拥有SignalR背板,请不要使用群集中的实例!