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

IE 11 + SignalR не работает

Странное поведение происходит при использовании signalR с IE 11. Сценарий:

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

НО один метод, который не работает (performUpdate - для получения результатов запроса - это клиентский вызов сервера, а не клиент > сервеp > клиент) - никогда не вызывается. ЭТО ТОЛЬКО ПОЛУЧАЕТСЯ ПРИЗЫВАТЬ, КОГДА КОНСОЛЬ РАЗРАБОТЧИК ОТКРЫТО.

Вот что я пробовал:

Почему JavaScript работает только после открытия инструментов разработчика в IE один раз?

SignalR: в IE9 сообщения не могут быть получены клиентом до тех пор, пока я не нажму F12!!!!

Клиент SignalR не работает внутри контроллера AngularJs

Некоторые фрагменты кода

сторона диспетчера

При изменении выпадающего списка мы получаем текущие выбранные значения и отправляем обновления по проводу. (Это прекрасно работает).

$('#Selector').on('change', function(){
   var variable = $('#SomeField').val();
   ...
   liveBatchHub.server.updateParameters(variable, ....);
});

Сторона сервера

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

public void Update(string userId, Guid bId)
        {
            var context = GlobalHost.ConnectionManager.GetHubContext<LiveBatchViewHub>();
            context.Clients.User(userId).performUpdate(bId);
        }

Клиентская сторона (средство просмотра живых обновлений)

Это никогда не будет вызвано, если инструменты разработчика открыты

liveBatchHub.client.performUpdate = function (id) {
                    //perform update here
                    update(id);
                };

Edit

Немного больше информации, которая может быть полезной (я не уверен, почему это имеет значение), но это ТОЛЬКО, похоже, происходит, когда я выполняю вызовы server > client. Когда диспетчер меняет параметры поиска, обновляется клиентский сервеp > клиентский или диспетчер-клиент > сервеp > зритель-клиент, который, похоже, работает. После нажатия поиска служба в конвейере поиска вызывает сторону сервера performUpdate (сервеp > зритель-клиент). Не уверен, что это имеет значение?

Изменить 2 и окончательное решение

Я понимаю, что я оставил одну ключевую часть этого вопроса: мы также используем angular на этой странице. Полагаю, я слишком долго смотрел на нее и оставил это, извините. Я получил JDupont ответ, потому что он был на правильном пути: кеширование. Но не кеширование jQuery ajax, углы $http.

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

Взято из здесь:

myModule.config(['$httpProvider', function($httpProvider) {
    //initialize get if not there
    if (!$httpProvider.defaults.headers.get) {
        $httpProvider.defaults.headers.get = {};    
    }    

    // Answer edited to include suggestions from comments
    // because previous version of code introduced browser-related errors

    //disable IE ajax request caching
    $httpProvider.defaults.headers.get['If-Modified-Since'] = 'Mon, 26 Jul 1997 05:00:00 GMT';
    // extra
    $httpProvider.defaults.headers.get['Cache-Control'] = 'no-cache';
    $httpProvider.defaults.headers.get['Pragma'] = 'no-cache';
}]);
4b9b3361

Ответ 1

В прошлом я испытал подобное поведение в IE. Я могу знать о решении вашей проблемы.

IE кэширует некоторые запросы ajax по умолчанию. Вы можете попытаться отключить это глобально. Проверьте это: Как предотвратить IE от кеширования Ajax с помощью jQuery

В основном вы бы глобально отключили это следующим образом:

$.ajaxSetup({ cache: false });

или для конкретного запроса ajax, например:

$.ajax({
  cache: false,
  //other options...
});

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

Ответ 2

Если ваш код работает правильно с другими браузерами, проблема может быть связана с используемым транспортным методом SignalR. Они могут быть WebSocket, События с сервером, Forever Frame и Long Polling на основе поддержки браузера.

Рамка Forever предназначена только для Internet Explorer. Вы можете увидеть Введение в SignalR, чтобы узнать, какой транспортный метод будет использоваться в различных случаях (обратите внимание, что вы не можете использовать ни один из них на каждом браузер, например, IE не поддерживает события, отправленные сервером).

Вы можете понять, какой метод транспорта используется внутри концентратора, просто просмотрев запрос QueryString, который может быть полезен для ведения журнала:

Context.QueryString["transport"];

Я думаю, проблема связана с использованием Forever Frame по IE, потому что иногда это приводит к сбою SignalR в вызовах Ajax. Вы можете попытаться удалить поддержку Forever Frame в SignalR и заставить использовать оставшиеся поддерживаемые методы браузером со следующим кодом на стороне клиента:

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

Я показал некоторые реалии о SignalR и дал вам некоторые инструменты ведения журнала/трассировки для решения вашей проблемы. Для получения дополнительной информации добавьте дополнительные сведения:

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

  • Настройка ссылки браузера в среде IDE
  • проверить данные запроса/ответа на вкладку "Сеть" во время ее процесса.
  • Убедитесь, что вы не использовали зарезервированные имена на стороне сервера/клиента (возможно, путем переименования методов и переменных).

Также я думаю, что вам нужно использовать liveBatchHub.server.update(variable, ....); вместо liveBatchHub.server.updateParameters(variable, ....); в стороне Диспетчера, чтобы выполнить вызов сервера, так как вы должны использовать имя метода сервера после server.