2014-01-17 45 views
0

我有一个名称查找框,通过您的典型ajax请求操作。下面是每次按下字母时都会触发的Javascript的一般流程:停止请求服务器端

  • 如果ajax请求已打开,则中止它。
  • 如果超时已经创建,请将其销毁。
  • 设置新的超时运行以下在半秒:通过AJAX
  • 发送字符串“nameLookup.php”
  • 等待回应
  • 显示效果

的问题是,nameLookup .php是非常重要的资源。在某些情况下,多达10,000个名字正在从SQL数据库中提取,解密并与字符串进行比较。在正常情况下,请求可能需要5到60秒才能返回。

我完全明白,当您在客户端中止请求时,服务器仍在处理事件并发回结果。只是客户端知道忽略响应。但是服务器在处理所有这些请求时变得如此悬而未决。

所以,如果你这样做:

  • 请求1个
  • 中止请求1
  • 请求2
  • 中止请求2
  • 要求3
  • 等待请求响应3

服务器甚至没有在请求3上工作,直到它完成1和2 ...或者它只是在请求1和2上工作,以致请求3需要额外的很长时间。

我需要知道如何告诉服务器停止对请求1和2的工作,所以我可以腾出资源,以便在要求工作3

我使用Javascript &的jQuery在客户端。 PHP/Apache和SQL在服务器端。

+0

你试过缓存结果吗?我个人建议安装和使用memcached。添加一个类,你可以在1个月或1周后取决于你的需要 –

+0

也可以过期结果,看看下面的帖子http://stackoverflow.com/questions/13886501/ajax-abort-is-not-aborting -on-the-server-only-the-the-client –

+0

我同意你只是有一个架构问题的其他意见。被查询数据的基数是多少(即缓存是否合理)。什么是数据的大小?它是否适合特里结构或类似的搜索树,使查找效率更高? –

回答

-1

我已经想出了一个很好的解决方案,我已经测试过,它的工作非常好。只需要几行PHP代码即可放入任何需要大量资源的文件。

该解决方案利用来自服务器的Process Identifier (PID)。我们可以使用两个PHP函数:posix_getpid()获取当前的PID和posix_kill()来杀死另一个PID。这也假设你已经在其他地方调用了session_start()。

下面的代码:

//if any existing PIDs to kill, go through each 
if ($_SESSION['pid']) foreach ($_SESSION['pid'] as $i => $pid) { 

    //if posix_kill returns true, unset this PID from the session so we don't waste time killing it again 
    if(posix_kill($pid,0)) unset($_SESSION['pid'][$i]); 

} 

//now that all others are killed, we can store the current PID in the session 
$_SESSION['pid'][]=posix_getpid(); 

//close the session now, otherwise the PID we just added won't actually be saved to the session until the process ends. 
session_write_close(); 

几件事情要注意:

posix_kill有两个值。第一个是pid,第二个应该是来自this list的信号常量之一。没有什么对我有任何意义,其他人似乎只使用0就成功了,而当我使用0时,它返回true。所以无论工作!

在资源密集型事物开始发生之前调用session_write_close()至关重要。否则,保存到会话中的新PID将不会实际保存到会话中,直到完成所有页面的处理。这意味着下一个过程将不知道取消还在继续的过程。

+1

这似乎是一个非常糟糕的解决方案......您不应该惹恼服务器上的进程,必须有更好的解决方案。 –

+0

@FabienWarniez嗯,我已经有了这件事,而过去需要一分钟才能完成的事情已经过去了3秒。杀死这样的进程有什么问题?我会崩溃服务器吗?我会打开一个安全漏洞吗? – rgbflawed

+1

不同的事情:1.根据脚本在杀死它时的行为,查杀进程可以使DB或文件系统处于随机状态。 2.可维护性3.根据您承载代码的位置,您可能并不总是有权这样做。 4.有一个原因,这是一个安全漏洞,你给你的代码太多的权限/权限,它最好是非常强大和防弹。 –

0
  1. 将数据库中的布尔值存储在表中或会话中。
  2. 让您的资源密集型脚本定期检查该值是否应该继续。如果数据库表示停止,那么脚本会自行取消(例如,通过在当前函数中调用return;)。
  3. 当您想要取消而不是调用abort();时,请发出AJAX请求将该值设置为false
  4. 下一次资源检查该值时,它将看到它必须停止。

潜在限制: 1.您的脚本没有定期检查数据库的方法。 2.根据脚本检查数据库的频率,可能需要几秒钟才能有效地终止脚本。

+0

这也是一个有趣的做法。我担心必须对SQL进行大量的额外调用才能检查是否应该继续。我也关心这个“定期检查”部分。定义周期性意义是非常困难的。当然,在这个资源密集的脚本中有很多循环正在进行,但是一个循环所花费的时间长度将完全不同,具体取决于所输入的输入以及从SQL中退出的结果。 – rgbflawed

+1

这就是为什么我建议会议。它可以是memcache,它可以是存储这个布尔值的任何方式,以便简单的AJAX调用可以读/写它。 –

+0

嗨@FabienWarniez,我刚来到这个线程寻找解决我的问题。我想停止浏览器“取消”的请求。当用户在第一个请求回答之前切换到另一个网页时会发生这种情况。当您在Chrome中按F12时,您可以以取消状态显示红色请求。这可以发生在每个请求的所有时间,我不想管理数据库存储并检查每个请求...(尽管很少是长btw,也许是20)。没有更好的伎俩吗?浏览器无法发送信号给服务器以取消已取消的请求(这是唯一知道它的地方)? –