what's the skinny on long polling with ajax and webapi...is it going to kill my server? and string comparisons
Asked Answered
H

2

6

I have a very simple long polling ajax call like this:

(function poll(){
    $.ajax({ url: "myserver", success: function(data){
        //do my stuff here

    }, dataType: "json", complete: poll, timeout: 30000 });
})();

I just picked this example up this afternoon and it seems to work great. I'm using it to build out some html on my page and it's nearly instantaneous as best I can tell. I'm a little worried though that this is going to keep worker threads open on my server and that if I have too big of a load on the server, it's going to stop entirely. Can someone shed some light on this theory? On the back end I have a webapi service (.net mvc 4) that calls a database, build the object, then passes the object back down. It also seems to me that in order for this to work, the server would have to be calling the database constantly...and that can't be good right???

My next question is what is the best way on the client to determine if I need to update the html on my page? Currently I"m using JSON.stringify() to turn my object into a string and comparing the string that comes down to the old string and if there's a delta, it re-writes the html on the page. right now there's not a whole lot in the object coming down, but it could potentially get very large and I think doing that string comparison could be pretty resource intensive on the client...especially if it's doing it nearly constantly.

bottom line for me is this: I"m not sure exactly sure how long polling works. I just googled it and found the above sample code and implemented it and, on the surface, it's awesome. I just fear that it's going to bog things down (on the server) and my way of comparing old results to new is going to bog thigns down (on the client).

any and all information you can provide is greatly appreciated.

TIA.

Haro answered 16/12, 2012 at 20:25 Comment(0)
S
10

I agreee with SLaks - i.e. use SignalR if you need realtime web with WebApi http://www.asp.net/signalr. Long polling is difficult to implement well, let someone else handle that complexity i.e. use SignalR (natural choice for WebApi) or Comet.

SignalR attempts 3 other forms of communication before resorting to long polling, web sockets, server sent events and forever frame (here).

In some circumstances you may be better of with simple polling i.e. a hit every second or so to update... take a look at this article. But here is a quote:

when you have a high message volume, long-polling does not provide any substantial performance improvements over traditional polling. In fact, it could be worse, because the long-polling might spin out of control into an unthrottled, continuous loop of immediate polls.

The fear is that with any significant load on your web page your 30 second ajax query could end up being your own denial of service attack.

Even Bayeux (CometD) will resort to simple polling if the load gets too much:

Increased server load and resource starvation are addressed by using the reconnect and interval advice fields to throttle clients, which in the worst-case degenerate to traditional polling behaviour.

As for the second part of you question.

If you are using long polling then your server should ideally only be returning an update if something actually has changed thus your UI should probably "trust" the response and assume that a response means new data. The same goes for any of the Server Push type approaches.

If you did move back down towards simple polling pullmethod then you can use the inbuilt http methods for detecting an update using the If-Modified-Since header which would allow you to return a 304 Not Modified, so the server would check the timestamp of an object and only return a 200 with an object if it had been modified since the last request.

Serpent answered 17/12, 2012 at 9:10 Comment(4)
great comments to both of you @Mark Jones and Aliostad thanks. With the minimal server load I currently have, I think just implementing long polling would suffice for me for now. I will look into SignalR more carefully down the road. I do however think that my implementation of long polling is incorrect as my server is continuously sending responses back to the client, and the client is continuously requesting them. I'm at a bit of a loss as to what I need to set up on the server side to only send changes down. Is that small bit of JS in my OP accurate? What do I need to do on server?Haro
@ChristopherJohnson there are some other questions about the "how" online e.g. #11792411, this will involve some asynchronous http handlers with call backs triggered by a server-side mechanism for detecting change (even if that is polling at the server side!) but in reality it will take you far less time to implement simple polling or take 10 mins and try a framework like SignalR hanselman.com/blog/…Serpent
great... thanks much for the considered response and feedback.Haro
FYI, If using signalR with Azure websites (not your own vm) and you are scaling out with multiple instances, there is going to be some extra work. For me it was easier to simple poll with my own mechanism. I only needed 10 second or longer intervals. It was either that or venture way off course down a huge rabbit hole and that was not in scope.Turbinate
C
13

OK, my two cents:

  1. As others said, SignalR is tried and tested code so I would really consider using that instead of writing my own.
  2. SignalR does change some of the IIS settings to optimise IIS for this sort of work. So if you are looking to implement your own, have a look at IIS setting changes done in SignalR
  3. I suppose you are doing long polling so that your server could implement some form of Server Push. Just bear in mind that this will turn your stateless HTTP machine into a stateful machine which is not good if you want to scale. Long polling behind a load ballancer is not nice :) For me this is the worst thing about server push.
  4. ASP.NET uses ThreadPool for serving requests. A long poll will hog a ThreadPool thread. If you have too many of these threads you might end up in thread starvation (and tears). As a ballpark figure, 100 is not too many but +1000 is.
  5. Even SignalR team say that the IIS box which is optimised for SingalR, probably not optimised for normal ASP.NET and they recommend to separate these boxes. So this means cost and overhead.

At the end of the day, I recommend to using long polling if you are solving a business problem (and not because it is just cool) because then that will pay its costs and overheads and headaches.

Countersink answered 17/12, 2012 at 13:46 Comment(0)
S
10

I agreee with SLaks - i.e. use SignalR if you need realtime web with WebApi http://www.asp.net/signalr. Long polling is difficult to implement well, let someone else handle that complexity i.e. use SignalR (natural choice for WebApi) or Comet.

SignalR attempts 3 other forms of communication before resorting to long polling, web sockets, server sent events and forever frame (here).

In some circumstances you may be better of with simple polling i.e. a hit every second or so to update... take a look at this article. But here is a quote:

when you have a high message volume, long-polling does not provide any substantial performance improvements over traditional polling. In fact, it could be worse, because the long-polling might spin out of control into an unthrottled, continuous loop of immediate polls.

The fear is that with any significant load on your web page your 30 second ajax query could end up being your own denial of service attack.

Even Bayeux (CometD) will resort to simple polling if the load gets too much:

Increased server load and resource starvation are addressed by using the reconnect and interval advice fields to throttle clients, which in the worst-case degenerate to traditional polling behaviour.

As for the second part of you question.

If you are using long polling then your server should ideally only be returning an update if something actually has changed thus your UI should probably "trust" the response and assume that a response means new data. The same goes for any of the Server Push type approaches.

If you did move back down towards simple polling pullmethod then you can use the inbuilt http methods for detecting an update using the If-Modified-Since header which would allow you to return a 304 Not Modified, so the server would check the timestamp of an object and only return a 200 with an object if it had been modified since the last request.

Serpent answered 17/12, 2012 at 9:10 Comment(4)
great comments to both of you @Mark Jones and Aliostad thanks. With the minimal server load I currently have, I think just implementing long polling would suffice for me for now. I will look into SignalR more carefully down the road. I do however think that my implementation of long polling is incorrect as my server is continuously sending responses back to the client, and the client is continuously requesting them. I'm at a bit of a loss as to what I need to set up on the server side to only send changes down. Is that small bit of JS in my OP accurate? What do I need to do on server?Haro
@ChristopherJohnson there are some other questions about the "how" online e.g. #11792411, this will involve some asynchronous http handlers with call backs triggered by a server-side mechanism for detecting change (even if that is polling at the server side!) but in reality it will take you far less time to implement simple polling or take 10 mins and try a framework like SignalR hanselman.com/blog/…Serpent
great... thanks much for the considered response and feedback.Haro
FYI, If using signalR with Azure websites (not your own vm) and you are scaling out with multiple instances, there is going to be some extra work. For me it was easier to simple poll with my own mechanism. I only needed 10 second or longer intervals. It was either that or venture way off course down a huge rabbit hole and that was not in scope.Turbinate

© 2022 - 2024 — McMap. All rights reserved.