Signalr - Присоединяйтесь к нескольким группам

Изменить: Дэвид Фаулер запросил полный код, чтобы попытаться воспроизвести проблему. Вот полный код

В дополнение к коду, воспроизведенному здесь, я также загрузил полное решение Visual Studio 2010 по следующему URL-адресу.

http://www.sendspace.com/file/lfeurf (срок действия URL-адреса истек и больше не работает)

Пожалуйста, не стесняйтесь скачать и протестировать его.

Вот мои выводы

  1. Добавление только одной группы в код Hub заставит приложение работать без проблем.
  2. Добавление 2 групп либо остановит работу сигнализатора, либо будет работать только в одном направлении. то есть: сообщение будет передано из браузера 1 в браузер 2, но не будет передано из браузера 2 в браузер 1.

Оригинальный вопрос: я использую Signalr 1.0.0-rc1 на веб-сайте MVC3. Иногда моим клиентам нужно принадлежать к нескольким группам. Вот код в моем концентраторе и javascript на стороне клиента

JavaScript и HTML на стороне клиента

<script type="text/javascript">
    //start signalr
    var message = $.connection.messageHub;

    // Declare a function on the message hub so the server can invoke it          
    message.client.send = function (message) {
        alert(message);
    }

    // Start the connection and join groups
    $.connection.hub.start();

    //bind click event of button to invoke send function on server
    $(document).ready(function () {
        $("#target").click(function () {
            message.server.send("Hello from signalr");
        });
    });
</script>

<button id="target">Click to send message to other clients</button>

Концентратор на стороне сервера

public class MessageHub: Hub
    {
        public Task AddGroups()
        {
            //add 1st group
            Groups.Add(Context.ConnectionId, "foo");
            //add 2nd group
            return Groups.Add(Context.ConnectionId, "foobar");
        }

        //this method will be called from the client
        public void Send(string message)
        {
            Clients.OthersInGroup("foobar").send(message);
        }

        //automatically join groups when client first connects
        public override Task OnConnected()
        {
            return AddGroups();
        }

        //rejoin groups if client disconnects and then reconnects
        public override Task OnReconnected()
        {
            return AddGroups();
        }

    }

Приведенный выше код должен добавить две группы к каждому клиенту при первом подключении, но это не работает. Я прошел через код С# с помощью отладчика, и никаких ошибок не выдается. Я также не вижу никаких ошибок javascript с помощью консоли Chrome, но функция отправки не вызывается на клиентах. Затем я изменил метод AddGroups(), чтобы добавить только одну группу, как показано ниже.

public Task AddGroups()
   {
        //dont add first group
        //Groups.Add(Context.ConnectionId, "foo");
        //add only second group
        return Groups.Add(Context.ConnectionId, "foobar");
   }

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


person Community    schedule 16.12.2012    source источник
comment
Как выглядит клиентский код?   -  person davidfowl    schedule 17.12.2012
comment
@dfowler — добавлен код на стороне клиента   -  person    schedule 17.12.2012
comment
Какое конкретное событие происходит и когда оно происходит. Я хочу воспроизвести проблему и мне нужен код EXACT, который вы использовали.   -  person davidfowl    schedule 17.12.2012
comment
@dfowler - Дэвид, я отредактировал свой вопрос, включив в него полный код. Кроме того, я также загрузил проект VS2010, демонстрирующий проблему, на sendspace.com/file/lfeurf . Вы должны иметь возможность создавать, запускать и воспроизводить проблему.   -  person    schedule 17.12.2012
comment
@dfowler - Дэвид, исправление halter73 сработало для меня идеально. Это ошибка, которую вы можете исправить в следующем выпуске, или я неправильно использовал OnConnected и OnReconnected?   -  person    schedule 18.12.2012
comment
Он зарегистрирован и исправляется.   -  person davidfowl    schedule 18.12.2012


Ответы (2)


Похоже, ваши проблемы заключаются в том, что return Groups.Add(Context.ConnectionId, "foobar"); в AddToGroups истекает через 5 секунд. Task, возвращенный из Groups.Add, не завершается, пока SignalR не проверит, что клиент с указанным connectionId получил команду добавления в группу. Если этого не произойдет в течение 5 секунд, Task отменяется. Похоже, в настоящее время существует ошибка, предотвращающая ожидание Groups.Add внутри OnConnected и OnReconnected.

Поскольку вы возвращаете отмененный Task из OnConnected и OnReconnected, сервер не позволяет клиенту установить соединение.

Обходной путь состоит в том, чтобы игнорировать Task, возвращенный из Groups.Add, следующим образом:

public class MessageHub: Hub
{
    public Task AddGroups()
    {
        //add 1st group
        Groups.Add(Context.ConnectionId, "foo");
        //add 2nd group
        return Groups.Add(Context.ConnectionId, "foobar");
    }

    //this method will be called from the client
    public void Send(string message)
    {
        Clients.OthersInGroup("foobar").send(message);
    }

    //automatically join groups when client first connects
    public override Task OnConnected()
    {
        AddGroups();
        return base.OnConnected();
    }

    //rejoin groups if client disconnects and then reconnects
    public override Task OnReconnected()
    {
        AddGroups();
        return base.OnReconnected();
    }

}
person halter73    schedule 17.12.2012
comment
вы, сэр, восхитительны! Как ты это понял? Большое спасибо за исправление. - person ; 18.12.2012
comment
Я действительно работаю над исправлением. Спасибо, что сообщили об ошибке. Я зарегистрировал проблему здесь: github.com/SignalR/SignalR/issues/1155 - person halter73; 18.12.2012

MyHub.cs

public async Task Subscribe(IEnumerable<string> groups)
    {
        foreach(var group in groups)
        {
            await Groups.Add(Context.ConnectionId, group);
        }
    }

Javascript:

$.connection.hub.start().done(function () {
                var groups = ["foo","bar"];

                tileHub.server.subscribe(groups)
});
person ChaseAucoin    schedule 23.03.2014