SignalR и HttpContext/Session
Я понимаю, почему SignalR не дает вам доступ к HttpContext. Однако это довольно проблематично для нас. Позвольте мне объяснить:
Наше приложение представляет собой приложение Multi-Tenant, в котором пользователь выбирает среду при входе в систему. Это в основном регистрирует имя ConnectionStringName в HttpSession. В нашем концентраторе SignalR нам нужно получить доступ к базе данных на Disconnect
. Но это невозможно, потому что на данный момент у нас нет HttpContext и мы не можем определить среду для записи.
Может ли кто-нибудь дать нам предложение решить эту проблему? Мы немного застряли в этом.
EDIT: Бонусная точка, если ваше решение работает в среде с балансировкой нагрузки.
Ответы
Ответ 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"];
Это может использовать некоторые нулевые проверки или быть чище, но, надеюсь, это сэкономит кому-то время.