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 отметил, что при этом возникает ошибка)
Ответы
Ответ 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 в обработчик отключения, чтобы начать и отправить были отключены от разъединения. Это решило проблему для меня.