Angularjs long polling
Asked Answered
D

1

9

I am trying to perform a simple long poll request in Angularjs - I make a GET request and it hangs on till the server responds. Then I make the request again and wait for the next response - and so on.

However, for some reason the code is quite unreliable and misses around 80% of the responses sent from the server.

Below is my code:

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

Is there something obvious that I am missing here?

The server can detect that the browser is connected, and the server does send a response but the code above does not get the response (no console output and no error). I tried making this request with postman (chrome extension) and the long-poll worked perfectly there so I think the problem is somewhere in here.

update: the problem occurs only on Google Chrome and only when there is more than one tab performing the long-poll simultaneously. There is some seemingly random behaviour on creating and closing new tabs with the long-poll.

Dedifferentiation answered 25/11, 2014 at 10:11 Comment(1)
This is only half of the story, as you haven't included the timeout code or the server side code, as such it's hard to diagnose reliably.Lail
D
6

I found out what was causing this. Chrome will only longpoll a given url one tab at a time. If a user has got multiple tabs open requesting the same longpoll, Chrome waits for the longpoll in the first tab to finish before starting the poll in the second tab.

I think that the browser looks at the long-poll request as a 'server that is not responding'. When you try to make the same request in a new tab, the browser does not actually make that same request again to conserve resources. If you look at the network tab, it will show a pending request. But that's a 'lie', the browser is actually waiting for the server to respond for the first tab's request. Once it gets a response from the server for the first tab's request, only then will it query the server for the second tab's request.

In other words, the browser (Chrome and Opera) will not normally make two long-poll requests to the same endpoint simultaneously - even if these requests are coming from two different tabs.

However, sometimes after a certain amount of time it decides to release request for the second tab as well. But I was not able to figure out any rule for this. If you have 3 tabs open with the same request, closing the first causes 2 simultaneous requests from the remaining two tabs. But if you have 6 tabs open, closing the first causes only 3 simultaneous requests and not 5. I'm sure there would be some rules governing this behaviour but I guess we have to write code assuming that the requests may or may not take place simultaneously and the browser may wait for one request to finish before working on the second.

Safari does not have this behaviour - it will make multiple requests via multiple tabs simultaneously. But Chrome and Opera do show this behaviour.

So rather than 'broadcasting' data simultaneously to all connected clients, I am now changing my code to use timestamps to figure out how much data a client needs and then send that data.

Dedifferentiation answered 25/11, 2014 at 16:3 Comment(2)
One way is this: add a temporary random suffix to each url and ignore it at the server. Like this: localhost:8080/longpoll?rand=12345 and ignore the rand part when you parse the url in server. This way, from the browser's perspective every tab is trying to long-poll a different url (the rand number would be different) - even though its actually the same url from the server's perspective. Hence you get simultaneous longpolls even with multiple tabs. This is one way to deal with it.Dedifferentiation
@rbaghbanli yes and for that temporary part you can use current time stamp, it will be unique every time :)Aceydeucy

© 2022 - 2024 — McMap. All rights reserved.