解决最大持久连接,放置GET请求

时间:2019-06-18 22:42:34

标签: javascript rest firefox browser

我正在构建RESTful服务器,并为此编写一个javascript客户端。客户端的首页显示了数据库中数据的一些统计信息。特别是:我有一个6×3的表,其中的每个单元格均以'...'文本初始化,并具有一个query数据字段。在document.ready(客户端)上,我调用以下代码:

$('#home-page table td').map(function (i, x) {
  $.getJSON("/url/count?q=" + $(x).data('query'),
            function(data){
              $(x).text(data['__total__'])
            });
})

及其作用是,它在18个表单元中的每个单元上执行内部未命名函数,将对应的查询发送到我的服务器,并注册一个同样未命名的回调以处理结果。服务器执行数据库查询,然后计算结果中的项目,然后返回一个元素的字典。

现在有趣的是,Firefox将保留第7个请求,等待前6个请求之一处理。我曾以为是服务器中的内容,但是感谢this questionthis page,我可以确认它在我的Web浏览器中是一个限制。

Splitting my server over three or four ports听起来很糟糕。

也要调整设置,我不想让每个用户都这样做。

相比于默认的6限制,此图显示了如果我可以同时放置18个GET请求的响应时间。红色是blocked时间。

network timings

或者我放弃,并且一次全部更新表,但是我喜欢单元格一个接一个地更新的效果,这至少要花费所有请求最多的时间。

或者我可以对单元格进行排序,以便最有可能首先请求最快的单元格(三列第一行中的6个单元格显示select count(*) from table_i的结果)。接下来的两列仍然会有相同的问题。

那么我该如何解决这个问题,否则通常会满足要求:所有请求都在同一时间提出;每个结果准备就绪后都会收到。

我有一个主意,我将其详细解释为一个答案,但我不知道你们会做什么。


这是问题的开头文字,直到我找到问题的真正根源。


这是从日志中看的样子:

$ mix phx.server
Generated luke app
[info] Running LukeWeb.Endpoint with Cowboy using http://0.0.0.0:4000
15:00:56 - info: compiled 6 files into 2 files, copied 3 in 2.8 sec
[info] GET /
[info] Sent 200 in 56ms
[info] GET /url/count
[info] GET /url/count
[info] GET /url/count
[info] GET /url/count
[info] GET /url/count
[info] GET /url/count
[info] Sent 200 in 678ms
[info] GET /url/count
[info] Sent 200 in 1675ms
[info] GET /url/count
[info] Sent 200 in 2859ms
[info] GET /url/count
[info] Sent 200 in 1895ms
[info] GET /url/count
[info] Sent 200 in 3956ms
[info] Sent 200 in 3963ms
[info] GET /url/count
[info] GET /url/count
[info] Sent 200 in 657ms
[info] GET /url/count
[info] Sent 200 in 4801ms
[info] GET /url/count
[info] Sent 200 in 1196ms
[info] GET /url/count
[info] Sent 200 in 1511ms
[info] GET /url/count
[info] Sent 200 in 4882ms
[info] GET /url/count
[info] Sent 200 in 2950ms
[info] GET /url/count
[info] Sent 200 in 1306ms
[info] Sent 200 in 1099ms
[info] Sent 200 in 1880ms
[info] Sent 200 in 2349ms
[info] Sent 200 in 4885ms
[info] Sent 200 in 3558ms

服务器端,最相关的代码是这样的(我还没有实现任何东西,这只是一个随机的睡眠时间):

defmodule LukeWeb.CountController do
  use LukeWeb, :controller

  def index(conn, _params) do
    sleeping = :crypto.rand_uniform(500, 5000)
    :timer.sleep(sleeping)
    result = %{"__total__" => sleeping}
    json conn, result
  end
end

还有router.ex的各个部分:

defmodule LukeWeb.Router do
  use LukeWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/url", LukeWeb do
    pipe_through :api

    get "/count", CountController, :index
  end
end

1 个答案:

答案 0 :(得分:0)

我的想法基于令牌和递归。我将所有请求作为一个查询数组一次放置,然后我会立即收到一个令牌,用于标识请求集。

然后,cash_token函数将令牌提供给服务器,并使用以下结构注册用于处理它的回调:

function cash_token(token, args) {
  var itr, itd, ispan, btn;
  $.getJSON("/browse/cash-token/{}".format(token), function(data) {
   .
   .
   .
    if (not_yet_done) {
         setTimeout(partial(cash_token, token, args), 1);
    }
})}

这些仅是客户端方面的准则,显然我还没有编写最终代码,而服务器端,我需要了解更多Elixir

({partialformat不是标准javascript)