SignalR: как остановить создание нового подключения при перезагрузке страницы

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

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

Я использую SignalR 2.0 в проекте ASP.NET MVC4, есть помощь??


person Saurabh Sashank    schedule 27.11.2013    source источник
comment
вы должны хранить статус пользователя в базе данных или где-то еще. и должен уведомлять других пользователей всякий раз, когда пользователь выходит из системы, а не когда signalR закрывает соединение   -  person Ronak Patel    schedule 27.11.2013
comment
signalR закрывает соединение при каждой перезагрузке страницы, как остановить это поведение? @Патель   -  person Saurabh Sashank    schedule 27.11.2013
comment
то, что идеально, субъективно, основано на требованиях @Patel, с моей точки зрения это странно.   -  person Saurabh Sashank    schedule 27.11.2013


Ответы (1)


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

В аналогичном сценарии, над которым я работаю, мы сохраняем идентификаторы подключения OnConnect и удаляем их OnDisconnect. Когда сообщение необходимо отправить данному пользователю, мы отправляем его всем его идентификаторам подключения. Это гарантирует, что сообщение будет доставлено на все вкладки/окна.

ИЗМЕНИТЬ 1 следующее в ответ на комментарии @Saurabh:

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

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

_chatHub.server.reJoinRooms();

Затем концентратор может запрашивать комнаты пользователя по UserId, а не по ConnectionId.

public Task ReJoinRooms()
{
// get the user's rooms from your repository
// optionally get the user's connectionIds from your repository
// Clients.Caller.onJoinRooms(rooms);
// or Clients.Clients(_connectionIds).onJoinRooms(rooms);
}

Затем клиент может решить, предпринимать ли какие-либо действия:

$chatModule.client.onJoinRooms = function (rooms) {
   for (var i in rooms) {
           var _room = rooms[i];
           // if I'm not already in this room, add it to my rooms
           console.log('joining room', _room)
       }
}

Вы можете снять это разными способами. Клиент также может владеть областью запоминания комнат вместо репозитория на стороне сервера.

ИЗМЕНИТЬ 2

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

В этом случае каждый пользователь может вместо этого присоединиться к личным каналам (т. е. присоединиться к каналу, названному в соответствии с GUID пользователя). Мы будем отслеживать каждого пользователя, связанного с группой. Когда сообщение отправляется этой группе, мы перебираем этих пользователей и публикуем сообщение в каждом канале.

person andes    schedule 27.11.2013
comment
Я согласился, я также следую той же стратегии прямо сейчас, но проблема в том, что я показываю пользователей, подключенных к серверу, поэтому, когда пользователь переходит на какую-то другую страницу, он больше не отображается в сети. я хочу сделать соединение постоянным, пока он использует приложение, а не страницу. @анды - person Saurabh Sashank; 27.11.2013
comment
Ах, верно. Вы можете сохранить статус пользователя во время его сеанса, а не статус, являющийся функцией его connectionId. Также для переходов, таких как повторное присоединение к комнате, вы можете включить логический параметр, чтобы указать, что пользователь повторно подключается, и в этом случае вы можете проглотить обычные сообщения, которые будут отправлены для такого события. - person andes; 27.11.2013
comment
Как определить, что тот же пользователь повторно подключается, так как идентификатор соединения — это GUID, можете ли вы предоставить для него фрагмент кода. Это будет полезно @andes - person Saurabh Sashank; 27.11.2013