Связь SignalR Hub-2-Hub с объединительной платой SQL в ASP.NET Owin

У меня есть ASP.NET Owin Web Api с балансировкой нагрузки, что означает, что существует несколько его экземпляров, которые не знают друг друга. Веб-API содержит концентратор SignalR с объединительной платой SQL Server (для синхронизации между экземплярами), поэтому клиенты могут обмениваться сообщениями независимо от того, к какому экземпляру веб-API они подключены. Пока все работает.

Данные клиентской сессии хранятся в db. Эта информация нужна веб-API для обработки запросов клиента. Поскольку было бы слишком медленно читать данные сеанса из базы данных для каждого клиентского запроса, веб-API считывает их только один раз (по первому запросу из клиентского сеанса) и кэширует их в памяти. Это также работает с несколькими экземплярами веб-API, поскольку каждый экземпляр хранит свой собственный кеш данных сеанса.

Но теперь клиентам должно быть разрешено изменять, например, язык, что приводит к обновлению языка в данных сеанса, хранящихся в базе данных. Экземпляр веб-API, который обрабатывает запрос на изменение языка, конечно, может реагировать на измененные данные сеанса и очищать сеанс из своего кеша, что приведет к повторному считыванию данных сеанса из базы данных при следующем клиентском запросе. Но другие экземпляры веб-API не знают об изменении данных сеанса, их кеши теперь содержат устаревшие данные сеанса.

Экземпляр веб-API, который обрабатывает запрос на изменение языка, каким-то образом должен уведомить другие экземпляры об удалении их кеша для сеанса xyz. К сожалению, экземпляры не знают друг друга, но все экземпляры содержат концентраторы SignalR, которые синхронизируются через объединительную панель сервера SingalR SQL.

К сожалению, концентратор SignalR не может напрямую отправлять и получать сообщения. Для этого необходим HubConnection (клиент). Итак, идея состоит в том, что когда каждый экземпляр веб-API подключается к своему собственному концентратору SignalR, он сможет отправлять сообщения самому себе, которые затем распространяются на другие экземпляры через синхронизацию объединительной платы SQL-сервера. Но HubConnection можно установить только с помощью URL-адреса (http: // host: port / signalr), но экземпляр веб-API не знает своего собственного базового URL-адреса.

Итак, наконец, мой вопрос: есть ли способ установить соединение HubConnection с концентратором, работающим в том же процессе, без предоставления URL-адреса (у меня есть доступ к объекту концентратора)? Если нет, есть ли способ для концентратора SignalR распространять сообщения и прослушивать сообщения через объединительную плату без клиента (связь концентратора-2-концентратора)? Если нет, что еще я могу сделать, чтобы уведомить другие экземпляры моего веб-API с балансировкой нагрузки и посоветовать им удалить кеш данных сеанса?


person thoros1179    schedule 16.12.2020    source источник
comment
_1 _ ??? Напротив, и все примеры показывают именно это, например, Как вызвать клиентские методы из класса Hub   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
В чем собственно вопрос? Что вы имеете в виду под hub-2-hub communication? Вы пытаетесь использовать SignalR для чего-то, для чего он не предназначен? Его задача - отправлять сообщения клиентам, а не заменять веб-API или другие HTTP-API.   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
@PanagiotisKanavos: но мне нужен концентратор для отправки сообщения другому концентратору, который синхронизируется через объединительную плату, а не клиенту. Я объяснил это довольно ясно imo. Я также попросил альтернативные способы, если это невозможно или не предназначено для такого использования.   -  person thoros1179    schedule 16.12.2020
comment
SignalR не в этом. Вопрос не совсем ясен, там много текста, в котором по существу задается Can SignalR be used to send notifications between hubs in a farm?, а ответ - No, that's not what it's for. реальный вопрос, похоже, не имеет никакого отношения к SignalR - как обновить информацию о сеансе клиента или даже как исправить проблемы с производительностью базы данных.   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Если вы исправите реальную проблему, вам не придется использовать только сеанс в памяти, потому что это то, что вы делаете. Если сеанс загружается только один раз, по сути, он только в памяти. Что в данном случае означает «медленно»? Почему загрузка сеанса медленная? Слишком много данных? Отсутствуют индексы? Недостаточно мощный сервер базы данных?   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Если у вас такой высокий трафик (сколько?), Что обычная таблица базы данных является проблемой, вы можете использовать таблицу в памяти в SQL Server или кеш Redis для хранения сеанса. Вы пытаетесь эмулировать распределенный кеш Redis. Почему бы не использовать актуальный кеш Redis? Попытка заставить веб-серверы работать как узлы кеша - нетривиальная задача. Microsoft долгое время пробовала это с помощью AppFabric Cache, прежде чем отказаться от него в пользу Redis.   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Опять же, в чем же настоящая проблема? Довольно часто проблемы с большими данными или высоким трафиком вызваны ошибками, неправильной конфигурацией или просто неадекватным оборудованием. Устранить настоящую проблему проще и дешевле, чем пытаться ее скрыть   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Например, что, если в одну и ту же настройку внесены два изменения? Даже если SignalR действовал как, например, MSMQ, и отправлял сообщения между узлами, как это решило бы проблему параллелизма? SignalR зависит от объединительной платы для решения этой проблемы, он не может сделать это сам. Вы просите SignalR не просто отправлять сообщения между хабами, вы просите его стать Redis   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Распространяет В статье о кэшировании в ASP.NET Core упоминается несколько различных способов хранения состояния сеанса: база данных, Redis или NCache. Вы пробовали NCache?   -  person Panagiotis Kanavos    schedule 16.12.2020
comment
Интерфейс IDistributedCache указал мне правильное направление, спасибо.   -  person thoros1179    schedule 17.12.2020


Ответы (1)


Решено с помощью распределенного кеширования (IDistributedCache), как упоминал Панайотис Канавос в комментариях.

person thoros1179    schedule 17.12.2020