Angularjs长期投票

时间:2014-11-25 10:11:03

标签: javascript angularjs long-polling

我正在尝试在Angularjs中执行一个简单的长轮询请求 - 我发出一个GET请求,它会挂起,直到服务器响应。然后我再次提出请求并等待下一个响应 - 依此类推。

但是,由于某些原因,代码非常不可靠,并且错过了从服务器发送的大约80%的响应。

以下是我的代码:

main.messages=[];
...
main.poll=function(){
  $http.get('http://localhost:8080/message')
  .success(function(data){
    console.log(data);
    main.messages.push(data);
    main.poll();
  })
  .error(...)
};

我有什么明显的遗失吗?

服务器可以检测到浏览器已连接,服务器确实发送了响应,但上面的代码没有得到响应(没有控制台输出也没有错误)。我尝试用postman(chrome扩展)发出这个请求,并且长轮询在那里工作得很好所以我认为这个问题就在这里。

更新:问题仅发生在Google Chrome浏览器上,并且仅当有多个标签同时执行长轮询时才会出现问题。使用长轮询创建和关闭新选项卡时会出现一些看似随机的行为。

1 个答案:

答案 0 :(得分:6)

我发现了造成这种情况的原因。 Chrome一次只能为一个标签提供一个标签。如果用户打开多个标签请求相同的长镜头,则Chrome会在第二个标签中开始轮询之前等待第一个标签中的longpoll完成。

我认为浏览器将长轮询请求视为未响应的服务器'。当您尝试在新选项卡中发出相同的请求时,浏览器实际上不会再次发出相同的请求以节省资源。如果查看网络选项卡,它将显示待处理的请求。但这是一个“谎言”,浏览器实际上正在等待服务器响应第一个标签的请求。一旦它从服务器获得第一个选项卡请求的响应,它才会向服务器查询第二个选项卡的请求。

换句话说,浏览器(Chrome和Opera)通常不会同时向同一个端点发出两个长轮询请求 - 即使这些请求来自两个不同的选项卡。

但是,有时候在一定时间后它也会决定释放第二个标签的请求。但我无法找出任何规则。如果您使用相同的请求打开了3个选项卡,则关闭第一个选项卡会导致其余两个选项卡同时发出2个请求。但是如果你有6个标签打开,关闭第一个标签只会导致3个同时请求,而不是5个。我确定会有一些规则控制这种行为,但我想我们必须编写代码,假设这些请求可能会也可能不会同时发生,浏览器可能会等待一个请求完成,然后才开始工作。

Safari没有此行为 - 它会同时通过多个标签发出多个请求。但Chrome和Opera确实显示了这种行为。

所以而不是'广播'数据同时发送到所有连接的客户端,我现在正在更改我的代码以使用时间戳来计算客户端需要多少数据然后发送数据。