2014-11-25 155 views
9

我想在Angularjs中执行一个简单的长轮询请求 - 我发出GET请求,并挂起直到服务器响应。然后我再次发出请求并等待下一个响应 - 等等。Angularjs长轮询

但是,由于某种原因,该代码是相当不可靠的,错过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(...) 
}; 

有没有,我很想念这里的东西明显?

服务器可以检测到浏览器被连接,并且服务器不发送响应而上面的代码没有得到响应(无控制台输出和无差错)。我试着用邮差(扩展名为chrome)提出这个请求,并且长时间轮询在那里完美工作,所以我认为问题出现在这里。

更新:该问题仅在谷歌浏览器中出现,并且只有当多个选项卡同时执行长轮询时才会发生。在创建和关闭新的选项卡时,有一些看似随机的行为。

+0

这只是故事的一半,因为您没有包含超时代码或服务器端代码,因此很难可靠地进行诊断。 – 2014-11-25 10:16:19

+0

超时码? – jitin 2014-11-25 10:19:41

回答

6

我发现是什么导致了这一点。 Chrome浏览器只会一次性抛出给定网址一个标签。如果用户有多个选项卡打开请求相同的longpoll,Chrome会在第一个选项卡中等待第二个选项卡中的轮询开始之前完成第一个选项卡中的longpoll。

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

换句话说,浏览器(Chrome和Opera)通常不会做两个长查询请求,同时在相同的终点 - 即使这些请求是由两种不同的标签来。

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

Safari不具备此行为 - 它会同时通过多个选项卡发出多个请求。但是Chrome和Opera确实显示了这种行为。

因此,而不是同时向所有连接的客户端“广播”的数据,我现在改变我的代码以使用时间戳来计算出有多少数据在客户端的需求,然后发送数据。

+0

Chrome/Opera的任何已知解决方法? – 2015-01-06 15:37:44

+7

一种方法是:为每个网址添加一个临时随机后缀,并在服务器上忽略它。像这样:'localhost:8080/longpoll?rand = 12345',并且在解析服务器中的url时忽略rand部分。这样,从浏览器的角度来看,每个标签都试图长时间轮询一个不同的URL(即使其数量不同),即使它从服务器的角度来看也是一样的。因此,即使有多个选项卡,您也可以同时获得长时间投掷。这是处理它的一种方法。 – jitin 2015-01-08 03:39:32

+2

@rbaghbanli是的,对于那个可以使用当前时间戳的临时部分,每次都会是唯一的:) – 2015-04-27 10:43:51