4

У меня есть следующая ситуация: у меня есть приложение SignalR, в котором я использую Autofac в качестве зависимого преобразователя.SignalR & Autofac - Redis backplane scaleout

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 вы создаете конфигурацию с нуля. Вы не должны ссылаться на GlobalHost везде, где используется интеграция OWIN.

Как Startup класс настроен прямо сейчас:

var resolver = new AutofacDependencyResolver(container); 
resolver.UseRedis("serverIp", portNumber, "password", "channelName"); 

поэтому я создаю новый resolver типа AutofacDependencyResolver и успешно подключается к Redis PubSub. Однако проблема заключается в том, что если я попытаюсь отправить одно сообщение, это сообщение будет повторяться тысячи раз.

(В консоли Chrome для отправки одного сообщения с сервера я заканчиваю бесконечный цикл, и клиент получает его бесконечно много раз).

Итак, вопрос заключается в следующем: Как настроить SignalR Redis scaleout при использовании Autofac в качестве зависимого преобразователя (обратите внимание: нет никаких обстоятельств, когда я могу использовать другой способ восстановления зависимостей).

Спасибо!

EDIT: Если вы хотите получить дополнительную информацию о решении, here is the repo без этой линии:

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

Спасибо!

EDIT: Я чувствую, что я должен прояснить некоторые вещи: Если я использую resolver.UseRedis();, каждое сообщение, которое будет обычно отправляется (один раз) отправляется много раз - так что, если я подписаться на «Channelname» в Redis с помощью subscribe "channelName", я считаю, это должно соответствовать поведению на клиенте: каждое сообщение отправляется несколько раз.

Следующее, что нужно сделать, это иметь базовое приложение SignalR без Autofac и посмотреть, как работает Redis, хотя я считаю, что это проблема, связанная с Autofac, более конкретно связанная с конфигурацией.

Спасибо!

ОБНОВЛЕНИЕ: По-видимому, такое же поведение наблюдается в базовом приложении SignalR без Autofac. Проблема не имеет ничего общего с Autofac.

ответ

1

Хорошо, я узнал, что происходит:

Сервер Redis я использовал был сконфигурирован, чтобы иметь несколько экземпляров, работающих вместе в кластере.

По умолчанию, если у вас есть кластер Redis и публиковать сообщение на канале в любом экземпляре, это сообщение будет перенаправлено по умолчанию на все остальные экземпляры.

В клиенте Redis Cluster клиенты могут подписаться на каждый узел, а также могут публиковать на всех других узлах. Кластер будет следить за тем, чтобы опубликованные сообщения были перенаправлены по мере необходимости. Текущая реализация будет просто транслировать каждое опубликованное сообщение на все остальные узлы.

The Redis cluster specification.

Скорее всего, реализация SignalR настроена принять любое сообщение, приходящее из Redis, поэтому мое странное поведение.

Решение состоит в том, чтобы иметь экземпляр Redis, который не находится в кластере, и все работает нормально.

Если вы хотите иметь объединительную панель SignalR, не используйте экземпляр из кластера!

Смежные вопросы