How does javascript long polling work?

Hey. I understand that with a long survey, you continue to communicate with the server for a long time, until you get a response from the server, and then run the survey again and wait for the next response. However, I don't seem to understand how to encode it. There is the following code that uses a lengthy survey, but I don't seem to understand it

(function poll(){ $.ajax({ url: "server", success: function(data){ //update page based on data }, dataType: "json", complete: poll, timeout: 30000 }); })(); 

But how is the connection open. I understand that the poll function starts again after receiving a response from the server. But how to open a connection?

Edit1: - It would be great if someone could also explain what would actually happen from time to time

+6
source share
7 answers

The client cannot force the server to keep the connection open. The server simply does not close the connection. The server will have to say at some point "what is it, there is no more content there, yet." With a long poll, the server simply never does this and forces the client to wait for more data, which it gradually depletes as updates arrive. This is a long survey.

On the client side, you can periodically check the data that has already been received, while the request is not yet completed. Thus, data can sometimes be sent from the server over the same open connection. In your case, this does not work, the success callback only works when the request completes. This is basically a cheap form of lengthy polling in which the server forces the client to wait for an event, sends data about this event, and then closes the connection. The client accepts this as a trigger, processes the data, and then reconnects to the server to wait for the next event.

+7
source

I think this makes it difficult to understand that the discussion focuses on client-side programming.

Long polling is not only a client-side template, but requires the web server not to open a connection.

Reference Information. The client wants to receive notifications from the web server when something happens or is available, for example, tell me when a new letter arrives, without having to return and ask every few seconds.

  • The client opens a connection to a specific URL on the web server.
  • The server accepts the connection, opens the socket and sends control to any server code, processing this connection (say, a servlet or jsp in java or a route in RoR or node / express).
  • The server code waits until an event or information appears. For example, when an email arrives, he sees if there is any of the “pending connections” for a particular mailbox. If they are, then answer with the appropriate data.
  • The client receives the data, does its job, and then runs another polling request.
+6
source

You do not see how this works from this code, because the actual difference from the regular request is executed on the server.

Javascript just makes a regular request, but the server should not immediately respond to the request. If there is nothing worthy of return on the server (i.e. the change expected by the browser has not yet occurred), the server simply waits for support to open the connection.

If nothing happens on the server for some time, either the client side will disconnect and make a new request, or the server may select an empty result to save the stream.

+2
source

I was looking to do something with chess data results, where some will return immediately, but the last few results may return in 10-15 seconds. I created a quick little jQuery hack, but it does what I want (still not sure if it makes sense to use its tho):

 (function($) { if (typeof $ !== 'function') return; $.longPull = function(args) { var opts = $.extend({ method:'GET', onupdate:null, onerror:null, delimiter:'\n', timeout:0}, args || {}); opts.index = 0; var req = $.ajaxSettings.xhr(); req.open(opts.method, opts.url, true); req.timeout = opts.timeout; req.onabort = opts.onabort || null; req.onerror = opts.onerror || null; req.onloadstart = opts.onloadstart || null; req.onloadend = opts.onloadend || null; req.ontimeout = opts.ontimeout || null; req.onprogress = function(e) { try { var a = new String(e.srcElement.response).split(opts.delimiter); for(var i=opts.index; i<a.length; i++) { try { var data = JSON.parse(a[i]); // may not be complete if (typeof opts.onupdate==='function') opts.onupdate(data, i); opts.index = i + 1; } catch(fx){} } } catch(e){} }; req.send(opts.data || null); }; })(jQuery); 

Largely untested, but he seemed to be doing what you had in mind. I can think of all kinds of ways so that this might go wrong, though :-)

 $.longPull({ url: 'http://localhost:61873/Test', onupdate: function(data) { console.log(data); }}); 
+2
source

As requested, here is some kind of NodeJS pseudo-code:

 function respond_to_client(res,session,cnt) { //context: res is the object we use to respond to the client //session: just some info about the client, irrelevant here //cnt: initially 0 //nothing to tell the client, let long poll. if (nothing_to_send(res,session)) { if (cnt<MAX_LONG_POLL_TIME) { //call this function in 100 ms, increase the counter setTimeout(function(){respond_to_client(request_id,res,session,cnt+1)},100); } else { close_connection(res); //Counter too high. //we have nothing to send and we kept the connection for too long, //close it. The client will open another. } } else { send_what_we_have(res); close_connection(res); //the client will consume the data we sent, //then quickly send another request. } return; } 
+2
source

The connection is not persistent. It automatically closes when a response is received from the server, and the server closes the connection. With a long polling, the server should not immediately send data back. In ajax complete (when the server closes the connection), a new request is sent to the server, which opens a new connection again and begins to wait for a new response.

As already mentioned, the lengthy polling process is processed not only on the client side, but mainly on the server side. And not only the script server (in the case of PHP), but also the server itself, which does not close the hanged connection with a timeout.

FWIW, WebSockets use a constantly open connection with the server side, which allows you to receive and send data without closing the connection.

+1
source

I think no one explains why we need a timeout in the code. From jQuery Ajax docs:

Set the timeout (in milliseconds) for the request. This will override any global timeout with $ .ajaxSetup (). The waiting period begins when $ .ajax is called; if several other requests are being executed and the browser does not have connections available, it is possible that the request will time out before it can be sent

The timeout option does not really delay the next execution in X seconds. it sets the maximum timeout for the current call. Good article on timeouts - https://mashupweb.wordpress.com/2013/06/26/you-should-always-add-timeout-to-you-ajax-call-in-jquery/

+1
source

Source: https://habr.com/ru/post/952928/


All Articles