SignalR и HttpContext/Session - программирование

SignalR и HttpContext/Session

Я понимаю, почему SignalR не дает вам доступ к HttpContext. Однако это довольно проблематично для нас. Позвольте мне объяснить:

Наше приложение представляет собой приложение Multi-Tenant, в котором пользователь выбирает среду при входе в систему. Это в основном регистрирует имя ConnectionStringName в HttpSession. В нашем концентраторе SignalR нам нужно получить доступ к базе данных на Disconnect. Но это невозможно, потому что на данный момент у нас нет HttpContext и мы не можем определить среду для записи.

Может ли кто-нибудь дать нам предложение решить эту проблему? Мы немного застряли в этом.

EDIT: Бонусная точка, если ваше решение работает в среде с балансировкой нагрузки.

4b9b3361

Ответ 1

Это старый вопрос, но я оставляю свой ответ на всякий случай, если он будет полезен для всех.

Поскольку ваш концентратор расширяет Microsoft.AspNet.SignalR.Hub, он имеет доступ к свойству Контекст типа HubCallerContext

Это свойство предоставляет много информации от вызывающего:

  • ConnectionId
  • Заголовки
  • QueryString
  • Запрос
  • Cookies
  • Пользователь

В моем решении я использую имя пользователя, хранящееся в Context.User.Identity.Name как ключ в моем хранилище ключей/значений ( Redis в моем случае), чтобы сохранить отслеживать все соединения, которые пользователь имеет.

Вы можете переопределить OnConnnect и OnDisconnect, чтобы поддерживать список подключений, связанных с пользователем. Вы также можете хранить все, что хотите, вместе с идентификаторами соединений (ваши строки подключения пользователя в вашем случае).

Ответ 2

У меня была аналогичная проблема, так как мне нужно было идентифицировать посетителей, не прошедших проверку подлинности, в моем приложении, чтобы персонализировать их запросы в концентратор SignalR.

Я решил его, обратившись к "HttpContext.Current.Request.AnonymousId". Анонимный интерфейс сопоставляется с временной записью в самообучаемом объекте Session в базе данных SQL - по существу, эмулирует сеанс с поддержкой базы данных.

Вот некоторая соответствующая документация, если вы хотите настроить AnonymousId или инициализировать запись базы данных: http://msdn.microsoft.com/en-us/library/system.web.httprequest.anonymousid.aspx

Кроме того, вы должны иметь доступ к Контексту в OnDisconnected() следующим образом: Context.Request.GetHttpContext().

Надеюсь, это поможет.

Ответ 3

Вы можете использовать что-то вроде словаря для отслеживания ConnectionId пользователя при его подключении. Также использование SQL Server для хранения состояния сеанса также может помочь: http://support.microsoft.com/kb/317604

SignalR дает вам доступ к User.Identity.Name, которое вы можете использовать для отслеживания при запуске disoconnect().

Ответ 4

Тот факт, что вам нужно, чтобы ваше решение работало в среде с балансировкой нагрузки, подтверждает тот факт, что вам нужно сохранить строку подключения в чем-то отличном от сеанса. Хранилище с ключом (как вы его реализуете, не имеет значения), где ключ - это ConnectionId (единственная информация, доступная при отключении), а значение - строка соединения. Вы можете продолжать использовать Сессию в любом другом месте, если хотите, но я думаю, вы должны переместить все приложение, чтобы писать и читать оттуда, по крайней мере, для этой информации.

Ответ 5

Очевидно, вы можете использовать Context.GetHttpContext() в 3.0, чтобы получить HttpContext.

К вашему сведению, Signalr 3.0 больше не имеет объекта Context.Request. Контекст запроса может быть достигнут путем доступа к IHttpContextFeature in Context.Features[]. Я использовал следующее:

string myCookieValue = ((IHttpContextFeature)Context.Features[typeof(IHttpContextFeature)]).HttpContext.Request.Cookies["Value"];

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