【问题标题】:IE 11 + SignalR not workingIE 11 + SignalR 不工作
【发布时间】:2015-09-23 22:43:00
【问题描述】:

在 IE 11 中使用 signalR 时会发生奇怪的行为。场景:

我们有一些调度器类型的功能,调度器执行一些操作,而其他用户可以实时查看更新(查询)。发送的参数很好,无需打开开发者控制台即可在 IE 客户端更新。

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

这是我尝试过的:

Why JavaScript only works after opening developer tools in IE once?

SignalR : Under IE9, messages can't be received by client until I hit F12 !!!!

SignalR client doesn't work inside AngularJs controller

一些代码sn-ps

调度方

在下拉更改时,我们会获取当前选择的值并通过网络发送更新。 (这很好用)。

$('#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 调用的缓存。

取自here

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

【问题讨论】:

  • 您是否收到控制台错误?
  • 没有显示控制台错误
  • 您的应用是否引用了 JSON2?如果是,是否在引用 signalR.min.js 之前进行了引用?
  • 确保浏览器链接已启用。
  • 您的 js(客户端(实时更新查看器))代码中是否有任何基于控制台的功能(如 Console.log)?在打开开发控制台之前,这些功能在 IE 中不起作用,并且可能导致您的代码中断。

标签: asp.net-mvc internet-explorer iis signalr


【解决方案1】:

我过去在 IE 中遇到过类似的行为。我可能知道您的问题的解决方案。

IE 默认缓存一些 ajax 请求。您可能想尝试在全局范围内关闭此功能。看看这个:How to prevent IE from caching Ajax with jQuery

基本上你会像这样全局关闭它:

$.ajaxSetup({ cache: false });

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

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

我的 GET 请求缓存也有类似的问题。除非开发工具打开,否则我的更新功能只会触发一次。当它打开时,不会发生缓存。

【讨论】:

  • 如果问题确实是缓存,我想第一个调用应该可以正常工作。
【解决方案2】:

如果您的代码在其他浏览器上正常工作,那么问题可能来自 SignalR 使用的传输方法。它们可以是WebSocket服务器发送事件Forever FrameLong Polling 基于浏览器支持。

Forever Frame 仅适用于 Internet Explorer。您可以查看Introduction to SignalR 以了解在各种情况下将使用哪种传输方式(请注意,您不能在每个浏览器上都使用它们中的任何一种,例如IE doesn't support Server Sent Events)。

您可以通过查看请求的QueryString 了解在集线器内部使用的传输方法,这对于日志记录很有用:

Context.QueryString["transport"];

我认为问题可能来自 IE 使用 Forever Frame,因为有时它会导致 SignalR 在 Ajax 调用上崩溃。您可以尝试删除 SignalR 中的 Forever Frame 支持,并在客户端使用以下代码强制使用浏览器支持的其余方法:

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

我展示了有关 SignalR 的一些现实情况,并为您提供了一些日志记录/跟踪工具来解决您的问题。如需更多帮助,请提供更多详细信息:)

更新: 由于您的问题似乎很奇怪,而且我对您的代码没有足够的了解,所以我根据我的经验向您建议一些说明希望有用:

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

另外我认为你需要在 Dispatcher 端使用liveBatchHub.server.update(variable, ....); 而不是liveBatchHub.server.updateParameters(variable, ....); 来进行服务器调用,因为你应该在server 之后使用服务器方法名称。

【讨论】:

  • 谢谢 - 这是我尝试的首批解决方案之一。
猜你喜欢
  • 1970-01-01
  • 2016-05-07
  • 2015-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-06
  • 2017-11-08
  • 1970-01-01
相关资源
最近更新 更多