SignalR и HttpContext/сеанс

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

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

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

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


person Lodewijk    schedule 18.09.2012    source источник
comment
Вы все еще ищете решение здесь?   -  person Raciel R.    schedule 28.08.2013
comment
Мы реализовали эту функцию совершенно по-другому.   -  person Lodewijk    schedule 29.08.2013
comment
@Lodewijk, не могли бы вы поделиться своим другим способом? Я в такой же ситуации.   -  person Mario Levrero    schedule 14.11.2013
comment
Lodewijk и @MarioLevrero, можете ли вы решить проблему? Та же проблема здесь.   -  person Daniel Oliveira    schedule 20.07.2015


Ответы (5)


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

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

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

  • Идентификатор соединения
  • Заголовки
  • Строка запроса
  • Запрос
  • Печенье
  • Пользователь

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

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

person Raciel R.    schedule 29.08.2013
comment
К сожалению, кэширование на основе имени пользователя не работает, если у пользователя открыто несколько сеансов... - person Dave; 17.09.2013
comment
У меня была аналогичная проблема здесь: stackoverflow.com/questions/27729113/. Эта нить спасла меня от выдергивания волос. Я исправил свою проблему, но я не совсем понимаю проблему. Если бы кто-нибудь мог подойти и дать мне твердый ответ, это было бы здорово! Я ненавижу двигаться дальше, не понимая этого до конца. - person Tez Wingfield; 01.01.2015
comment
@dave Я до сих пор не вижу проблемы с наличием нескольких сеансов соединений signalR, но с сохранением состояния, как было предложено. - person eaglei22; 30.05.2017

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

Я решил это, обратившись к «HttpContext.Current.Request.AnonymousId». AnonymousId сопоставляется с временной записью в самореализуемом объекте сеанса в базе данных SQL, по сути, эмулируя сеанс, поддерживаемый базой данных.

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

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

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

person JDR    schedule 27.08.2013

Если вы используете ASP.NET Core SignalR 3.0 (не ASP.NET SignalR 2.1), вы можете использовать Context.GetHttpContext() для получения HttpContext.

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

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

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

person R. Hargrove    schedule 16.10.2019
comment
Этому вопросу 7 лет. Я сомневаюсь, что Signalr 3.0 был выпущен тогда. - person csabinho; 17.10.2019

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

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

person Steve    schedule 18.09.2012
comment
К сожалению, информация о пользователе недоступна: .. а также пользователь HubContext и файлы cookie не будут заполнены. (github.com/SignalR/SignalR/wiki/Hubs) - person Lodewijk; 18.09.2012
comment
Кроме того, мы находимся в среде с балансировкой нагрузки, поэтому отключение может закончиться на другом сервере, где словарь не заполнен. - person Lodewijk; 18.09.2012
comment
Я просмотрел некоторый предыдущий код, и Context.User.Identity.Name показывает текущего вошедшего в систему пользователя. Если среда сбалансирована по нагрузке, вам, возможно, стоит взглянуть на Redis для SignalR. github.com/ СигналР/СигналР/вики/ - person Steve; 18.09.2012
comment
Я имел в виду, что информация о пользователе не будет заполняться при отключении. Я полагаюсь на документы для этого. На самом деле не накачивал. - person Lodewijk; 19.09.2012

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

person Wasp    schedule 21.09.2012
comment
Состояние сеанса не является проблемой в среде с балансировкой нагрузки и не является проблемой уже как минимум десятилетие. - person Tor Haugen; 16.04.2013
comment
Прочитайте лучше вопрос перед голосованием, HttpContext недоступен с SignalR (или, по крайней мере, не был в то время), и с этой сессией - person Wasp; 16.04.2013
comment
На самом деле HttpContext и HttpContext.Current доступны, и только Session имеет значение null. - person Dave; 17.09.2013
comment
Это верно прямо сейчас, я почти уверен, что весь HttpContext был недоступен во время вопроса (год назад, SignalR 0.5), но это хороший момент, чтобы сделать обсуждение актуальным, спасибо :) - person Wasp; 17.09.2013