4

我有以下情况:我有一个 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();
    }
}

现在,来自 Microsoft 的官方 SignalR Redis 横向扩展文档声明我应该告诉GlobalHost.DependencyResolverto 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不再在应用程序中使用(即使我使用GlobalHostRedis 中绝对没有任何行为)(正如 Autofac 与 SignalR 和 Owin 的集成所表明的那样):

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 横向扩展(注意:没有任何情况下我可以使用另一个依赖解析器)。

谢谢!

编辑:如果您想了解有关解决方案的更多信息,这里是没有此行的 repo:

resolver.UseRedis("serverIp", portNumber, "password", "channelName");

谢谢!

编辑:我觉得我应该澄清一些事情:如果我使用resolver.UseRedis();,通常会发送(一次)的每条消息都会发送多次 - 所以如果我在 Redis 中订阅“channelName”,使用subscribe "channelName",我发现它与客户端的行为:每条消息被多次发送。

接下来要做的是有一个没有 Autofac 的基本 SignalR 应用程序,看看 Redis 的行为,虽然我觉得这是一个 Autofac 相关的问题,更具体地说与配置有关。

谢谢!

更新:显然,没有 Autofac 的基本 SignalR 应用程序中存在相同的行为。该问题与 Autofac 无关。

4

1 回答 1

1

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

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

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

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

Redis 集群规范。

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

解决方案是拥有一个不在集群中的 Redis 实例,并且一切正常。

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

于 2015-09-17T11:22:07.427 回答