IE 11 + SignalR不能正常工作

22

使用SignalR和IE 11一起出现了奇怪的行为。情况如下:

我们有一些调度程序功能,调度程序执行一些操作,其他用户可以实时看到更新(查询)。发送的参数正常传递,并在IE客户端上引起更新,而无需打开开发人员控制台。

但是唯一不起作用的方法(performUpdate - 获取查询结果 - 这是一个服务器>客户端调用,不是客户端>服务器>客户端)- 永远不会被调用。只有当开发人员控制台打开时才会被调用。

这是我尝试过的:

为什么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);
                };

编辑

以下信息可能会有所帮助(我不确定为什么会有所区别),但是只有在服务器与客户端之间的调用时才会发生这种情况。当调度程序更改搜索参数时,更新是客户端>服务器>客户端或调度程序-客户端>服务器>查看器-客户端,这似乎有效。当他们点击搜索后,搜索管道中的服务将在服务器端调用performUpdate(服务器>查看器-客户端)。不确定这是否重要?

编辑2和最终解决方案

我双眼血红,意识到我忘记了这个问题的一个关键部分:我们还在此页面上使用angular。猜想我已经盯着它看太久了,把它遗漏了 - 抱歉。我授予JDupont答案,因为他走在了正确的轨道上:缓存。但不是jQuery的ajax缓存,而是angulars $http。

为了让其他人不必花费数天/夜晚敲打头部,最终解决方案是使用angulars $http禁用ajax调用的缓存。

摘自这里

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';
}]);

你是否收到控制台错误? - Dave Alperovich
没有控制台错误显示。 - Jack
你的应用程序是否引用了JSON2?如果是,是在引用signalR.min.js之前引用的吗? - Dave Alperovich
确保浏览器链接已启用。 - Amirhossein Mehrvarzi
你的js(客户端(查看实时更新))代码中有没有类似Console.log这样的基于控制台的函数?这些函数在IE浏览器中需要打开开发者控制台才能正常工作,否则可能导致你的代码出错。 - Shashank Chaturvedi
显示剩余4条评论
2个回答

12

我曾经在IE中遇到过类似的问题。也许我知道如何解决你的问题。

IE默认会缓存一些ajax请求。您可以尝试全局关闭此功能。请查看此链接:如何使用jQuery防止IE缓存Ajax

基本上,您可以像这样全局关闭它:

$.ajaxSetup({ cache: false });

或者针对像这样的特定ajax请求:

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

我在进行GET请求缓存时遇到了类似的问题。我的更新函数只会在开发工具打开时才触发一次。当它被打开时,就不会发生缓存。


1
如果问题确实是缓存,我猜第一次调用应该能正常工作。 - Tasos K.

9
如果您的代码在其他浏览器上正常工作,那么问题可能来自SignalR使用的传输方法。它们可以基于浏览器支持使用WebSocket、服务器发送事件、Forever Frame和长轮询。Forever Frame仅适用于Internet Explorer。您可以查看介绍SignalR以了解在各种情况下将使用哪种传输方法(请注意,您不能在每个浏览器上使用它们,例如IE不支持服务器发送事件)。您可以通过查看请求的QueryString来了解正在Hub内使用的传输方法,这对于日志记录非常有用。
Context.QueryString["transport"];

我认为问题可能来自于IE使用Forever Frame,因为有时它会导致SignalR在Ajax调用时崩溃。您可以尝试在客户端使用以下代码移除SignalR中的Forever Frame支持,并强制使用浏览器支持的其他方法:
$.connection.hub.start({ transport: ['webSockets', 'serverSentEvents', 'longPolling'] });

我展示了一些关于SignalR的实际情况,并提供了一些日志/跟踪工具来解决您的问题。如果需要更多帮助,请提供额外的细节 :)

更新: 由于您的问题似乎非常奇怪,而且我对您的代码不够了解,因此根据我的经验,我建议您遵循以下指示,希望能有所帮助:

  1. 在适当的IDE中设置浏览器链接
  2. 检查网络选项卡请求/响应数据在其过程中
  3. 确保您没有在服务器/客户端中使用保留名称(可能通过重命名方法和变量)

此外,我认为您需要在调度程序侧使用liveBatchHub.server.update(variable, ....);而不是liveBatchHub.server.updateParameters(variable, ....);来进行服务器调用,因为您应该在server之后使用服务器方法名称。


谢谢 - 这是我尝试的第一种解决方案之一。 - Jack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接