jQuery 长轮询如何工作 javascript?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18560872/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how does long polling work javascript?
提问by Rasmus
Hi I understand that in long polling you keep the connection with the server open for long till you a get a response back from the server and then poll again and wait for the next response. However i dont seem to understand how to code it. There is this code below which uses long polling but I dont seem to get 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 kept open here. I understand that "poll" function is fired again once the response from the server is got.But how is the connection kept open?
但是这里的连接是如何保持打开的。我知道一旦得到服务器的响应,“轮询”功能就会再次被触发。但是连接是如何保持打开状态的?
Edit1:- It would be great if someone can also explain what would timeout actually do here
Edit1:- 如果有人也能解释超时实际上会在这里做什么,那就太好了
采纳答案by deceze
The client cannot force the server to keep the connection open. The serveris simply not closing the connection. The server will have to say at some point "that's it, there's no more content here, bye". In long polling, the server simply never does so and keeps the client waiting for more data, which it trickles out little by little as updates come in. That's long polling.
客户端不能强制服务器保持连接打开。该服务器根本就没有关闭连接。服务器将不得不在某个时候说“就是这样,这里没有更多内容,再见”。在长轮询中,服务器根本不会这样做,而是让客户端等待更多数据,随着更新的到来,这些数据一点一点地流出。这就是长轮询。
On the client side it's possible to check occasionally for the data which has already been received, while the request has not finished. That way data can occasionally be sent from the server over the same open connection. In your case this is not being done, the success
callback will only fire when the request has finished. It's basically a cheap form of long polling in which the server keeps the client waiting for an event, sends data about this event and then closes the connection. The client takes that as the trigger, processes the data, then reconnects to the server to wait for the next event.
在客户端,可以偶尔检查已接收的数据,而请求尚未完成。这样,数据偶尔可以通过相同的开放连接从服务器发送。在您的情况下,这没有完成,success
回调只会在请求完成时触发。它基本上是一种廉价的长轮询形式,其中服务器让客户端等待一个事件,发送有关该事件的数据,然后关闭连接。客户端以此为触发器,处理数据,然后重新连接到服务器以等待下一个事件。
回答by Brandon
I think what is making this confusing to understand is that the discussion is focused on the client-side programming.
我认为使这种理解混乱的原因是讨论的重点是客户端编程。
Long-polling is not strictly a client-side pattern, but requires the web server to keep the connection open.
长轮询严格来说不是客户端模式,而是要求 Web 服务器保持连接打开。
Background: Client wants to be notified by web server when something occurs or is available, for example, let me know when a new email arrives without me having to go back and ask every few seconds.
背景:客户端希望在发生某些事情或可用时通过 Web 服务器得到通知,例如,当有新电子邮件到达时让我知道,而我不必每隔几秒钟就回去询问。
- Client opens a connection to a specific URL on the web server.
- Server accepts connection, opens a socket and dispatches control to whatever server-side code handles this connection (say a servlet or jsp in java, or a route in RoR or node/express).
- Server code waits until the event or information is available. For example, when an email arrives, sees if any of the "waiting connections" are for the particular inbox. If they are, then respond with the appropriate data.
- Client receives data, does its thing, then starts another request to poll.
- 客户端打开与 Web 服务器上特定 URL 的连接。
- 服务器接受连接,打开一个套接字并将控制分派给处理此连接的任何服务器端代码(比如 java 中的 servlet 或 jsp,或者 RoR 或 node/express 中的路由)。
- 服务器代码等待事件或信息可用。例如,当电子邮件到达时,查看是否有任何“等待连接”是针对特定收件箱的。如果是,则使用适当的数据进行响应。
- 客户端接收数据,做它的事情,然后开始另一个轮询请求。
回答by Kris Oye
I was looking to do something with staggered data results where some would come back right away but the last few results might come back 10-15 seconds later. I created a quick little jQuery hack but it's kinda doing what I want (still not sure if it makes sense to use it tho):
我希望对交错的数据结果做一些事情,其中一些结果会立即返回,但最后几个结果可能会在 10-15 秒后返回。我创建了一个快速的小 jQuery hack,但它有点做我想做的事情(仍然不确定使用它是否有意义):
(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 it seemed to do what you had in mind. I can think of all sorts of ways it could go wrong, though ;-)
很大程度上未经测试,但它似乎按照您的想法行事。不过,我可以想到各种可能出错的方式;-)
$.longPull({ url: 'http://localhost:61873/Test', onupdate: function(data) { console.log(data); }});
回答by Hello World
As requested, here is some pseudo NodeJS code:
根据要求,这里有一些伪 NodeJS 代码:
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's 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;
}
回答by Guffa
You don't see how it works from that code only, because the actual difference from a regular request is done on the server.
您仅从该代码看不到它是如何工作的,因为与常规请求的实际区别是在服务器上完成的。
The Javascript just makes a regular request, but the server doesn't have to respond to the request immediately. If the server doesn't have anything worth returning (i.e. the change that the browser is waiting for hasn't happened yet), the server just waits which keeps the connection open.
Javascript 只是发出常规请求,但服务器不必立即响应请求。如果服务器没有任何值得返回的东西(即浏览器正在等待的更改尚未发生),则服务器只是等待以保持连接打开。
If nothing happens on the server for some time, either the client side will time out and make a new request, or the server can choose to return an empty result just to keep the flow going.
如果服务器在一段时间内没有发生任何事情,客户端将超时并发出新请求,或者服务器可以选择返回空结果以保持流程继续进行。
回答by VisioN
The connection is not kept open all the time. It is closed automatically when the response is received from the server and server closes the connection. In long polling the server is not supposed to send back data immediately. On ajax complete
(when server closes the connection) the new request is sent to the server, which opens a new connection again and starts to keep pending for new response.
连接并非一直保持打开状态。当收到来自服务器的响应并且服务器关闭连接时,它会自动关闭。在长轮询中,服务器不应该立即发回数据。在 ajax 上complete
(当服务器关闭连接时)新请求被发送到服务器,服务器再次打开一个新连接并开始等待新的响应。
As was mentioned, long polling process is handled not only by client side, but mainly by server side. And not only by server script (in case of PHP), but by server itself, which doesn't close the "hanged"connection by timeout.
如前所述,长轮询过程不仅由客户端处理,而且主要由服务器端处理。不仅通过服务器脚本(在 PHP 的情况下),而且通过服务器本身,它不会通过超时关闭“挂起”的连接。
FWIW, WebSocketsuse constantly opened connection with the server side, which makes possible to receive and send back the data without closing the connection.
FWIW,WebSockets使用不断打开的与服务器端的连接,这使得在不关闭连接的情况下接收和发送数据成为可能。
回答by Ilya Buziuk
I guess no one properly explain why do we need timeoutin the code. From jQuery Ajax docs:
我想没有人好好解释一下为什么我们需要超时的代码。来自 jQuery Ajax 文档:
Set a timeout (in milliseconds) for the request. This will override any global timeout set with $.ajaxSetup(). The timeout period starts at the point the $.ajax call is made; if several other requests are in progress and the browser has no connections available, it is possible for a request to time out before it can be sent
为请求设置超时(以毫秒为单位)。这将覆盖使用 $.ajaxSetup() 设置的任何全局超时。超时时间从 $.ajax 调用开始;如果其他几个请求正在进行中并且浏览器没有可用的连接,则请求可能会在发送之前超时
The timeout option indeed doesn't delay the next execution for X seconds. it only sets a maximum timeout for the current call. Good article about timeout stuff - https://mashupweb.wordpress.com/2013/06/26/you-should-always-add-timeout-to-you-ajax-call-in-jquery/
timeout 选项确实不会将下一次执行延迟 X 秒。它只为当前调用设置最大超时。关于超时的好文章 - https://mashupweb.wordpress.com/2013/06/26/you-should-always-add-timeout-to-you-ajax-call-in-jquery/