Подтвердить что ты не робот

SignalR не всегда готов после запуска(). Done()?

У меня есть небольшой проект, работающий с SignalR, однако я получаю очень несовместимое поведение.

<script type="text/javascript">
    $(function () {
        var chat = $.connection.brewBattleHub;
        $.connection.hub.start().done(function () {
            $("#broadcast").click(function () {
                // Call the chat method on the server
                chat.server.roll($("#username").val(), $("#drinkname").val());
            });
            chat.server.sendMessage("SignalR loaded...");
        });
    });
</script>

Когда я загружаю страницу, иногда я вижу сообщение "SignalR загружен", иногда я не являюсь.

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

есть start().done()? не гарантировать, что все готово?

=== addendum, я не ссылаюсь на jquery mobile (google отметил, что при этом возникает ошибка)

4b9b3361

Ответ 1

У меня была аналогичная проблема на этой неделе, за исключением того, что код в .done() никогда не запускался. Я включил протоколирование, и ничто не было зарегистрировано. При проверке консоли браузера ошибок не было. Глядя в средствах браузера dev, я мог видеть, что активности сети не было, когда я вызвал start(). Я подтвердил, что для прокси-сервера, возвращаемого $.connection.myhubclass, были все мои методы, поэтому я знал, что он может разговаривать с сервером и что код на стороне сервера был настроен правильно.

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

Тогда я заметил, что если бы я запустил метод запуска SignalR с консоли, это сработало бы. Это заставило меня поверить, что он пытался начать соединение слишком рано. Я решил свои проблемы, изменив код инициализации следующим образом:

$.connection.hub.start().done(function () {
  //Do interesting stuff
});

Для этого:

setTimeout(function () {
    $.connection.hub.start().done(function () {
      //Do interesting stuff
    });
}, 5000);

Я уверен, что смогу уменьшить эту задержку с 5 секунд до чего-то более короткого, но дополнительное время оказалось тем, что было необходимо, чтобы позволить браузеру подготовиться к созданию соединения. После того, как эта задержка была там, началось ведение журнала, возникло соединение, на клиенте была запущена серверная сторона OnConnected() и выполнена()().

После выяснения этого, я дважды проверил порядок загрузки javascript, думая, может быть, я загрузил что-то не по порядку, но порядок прав в соответствии с образцами SignalR. Я загружаю jQuery, SignalR,/signalr/hubs, а затем мой файл script, который инициализирует все.

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

Ответ 2

Попробуйте включить ведение журнала SignalR, чтобы помочь отладить вашу проблему. Вы также можете добавить обработчик fail в случае, если начало не выполняется (хотя это маловероятно). Как только вы это сделаете, вы можете просмотреть свои инструменты F12 в браузере, чтобы посмотреть журналы JS и сети.

<script type="text/javascript">
    $(function () {
        $.connection.hub.logging = true;
        var chat = $.connection.brewBattleHub;
        $.connection.hub.start().done(function () {
            $("#broadcast").click(function () {
                // Call the chat method on the server
                chat.server.roll($("#username").val(), $("#drinkname").val());
            });
            chat.server.sendMessage("SignalR loaded...");
        }).fail(function (reason) {
            console.log("SignalR connection failed: " + reason);
        });
    });
</script>

Ответ 3

Я нашел решение (насколько это возможно). Я загрузил SignalR в течение 7-8 секунд в IE11, я попытался "отладить" его в консоли, и я нашел причину задержки загрузки:

[13:13:04 GMT + 0200 (...)] SignalR: привязка к событию загрузки iframe.
[13:13:09 GMT + 0200 (...)] SignalR: foreverFrame время при попытке подключения.
[13:13:09 GMT + 0200 (...)] SignalR: Остановка навсегда кадра.

Прошло 5 секунд. чтобы попытаться загрузить iframe.

Оптимальное решение состоит в том, чтобы отключить iframe, поскольку IE11 обычно может использовать longPolling:

$.connection.hub.start(({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] }))

Ответ 4

У меня была аналогичная проблема, которая появилась только при попытке восстановить соединение после отключения. Я вызвал start() из обработчика разъединения, а затем попытался отправить сообщение из start.done(). Затем я получил сообщение об ошибке, что SignalR не был готов.

Я заметил в журнале, что start.done() разрешен немедленно, поэтому в моем случае был вызван вызов от разъединения, чтобы начать, а затем отправить. Я добавил setTimeout в обработчик отключения, чтобы начать и отправить были отключены от разъединения. Это решило проблему для меня.