SignalR & Autofac - масштабирование объединительной платы Redis
У меня следующая ситуация: у меня есть приложение 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();
}
}
Официальная документация по масштабированию Redis от SignalR от 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 нет абсолютно никакого поведения) ( как указывает интеграция Autofac с SignalR и Owin):
Распространенной ошибкой в интеграции OWIN является использование GlobalHost. В OWIN вы создаете конфигурацию с нуля. Вы не должны ссылаться на GlobalHost нигде при использовании интеграции OWIN.
Как Startup
класс настроен прямо сейчас:
var resolver = new AutofacDependencyResolver(container);
resolver.UseRedis("serverIp", portNumber, "password", "channelName");
поэтому я создаю новый resolver
типа AutofacDependencyResolver
и он успешно подключается к Redis PubSub. Проблема, однако, заключается в том, что если я попытаюсь отправить одно сообщение, оно будет повторяться тысячи раз.
(В консоли Chrome для отправки отдельного сообщения с сервера я зацикливаюсь, и клиент получает его бесконечное количество раз).
Итак, вопрос заключается в следующем: как настроить масштабирование Redis для SignalR при использовании Autofac в качестве средства разрешения зависимостей (примечание: ни при каких обстоятельствах я не могу использовать другое восстановление зависимостей).
Спасибо!
РЕДАКТИРОВАТЬ: Если вам нужна дополнительная информация о решении, вот репо без этой строки:
resolver.UseRedis("serverIp", portNumber, "password", "channelName");
Спасибо!
РЕДАКТИРОВАТЬ: я чувствую, что я должен уточнить некоторые вещи: если я использую resolver.UseRedis();
каждое сообщение, которое обычно отправляется (один раз), отправляется много раз - поэтому, если я подпишусь на "channelName" в Redis, используя subscribe "channelName"
Я считаю, что это соответствует поведению клиента: каждое сообщение отправляется несколько раз.
Следующее, что нужно сделать, - это иметь базовое приложение SignalR без Autofac и посмотреть, как Redis ведет себя, хотя я чувствую, что это проблема, связанная с Autofac, более конкретно связанная с конфигурацией.
Спасибо!
ОБНОВЛЕНИЕ: По-видимому, такое же поведение в базовом приложении SignalR без Autofac. Эта проблема не имеет ничего общего с Autofac.
1 ответ
Хорошо, я узнал, что происходит:
Сервер Redis, который я использовал, был настроен на одновременную работу нескольких экземпляров в кластере.
По умолчанию, если у вас есть кластер Redis и вы публикуете сообщение на канале в любом экземпляре, это сообщение будет пересылаться по умолчанию во всех остальных экземплярах.
В Redis Cluster клиенты могут подписываться на каждый узел, а также могут публиковать на любом другом узле. Кластер будет следить за тем, чтобы опубликованные сообщения пересылались по мере необходимости. Текущая реализация будет просто транслировать каждое опубликованное сообщение всем остальным узлам.
Скорее всего, реализация SignalR настроена на прием любого сообщения от Redis, поэтому мое странное поведение.
Решение состоит в том, чтобы иметь экземпляр Redis, который не находится в кластере, и все работает отлично.
Если вы хотите иметь объединительную плату SignalR, не используйте экземпляр из кластера!