关闭php上的窗口后关闭所有打开的资源

时间:2014-12-25 14:24:35

标签: javascript php

我有一个使用某些资源的对象,比如

class UseResources {

    protected $proc_open;

    public function __construct()
    {
        $this->proc_open = proc_open( ... );
    }

    public function cleanup()
    {
        proc_close($this->proc_open);
    } 
};

我试图在.unload事件上发送ajax请求,但这不是我要找的内容。

我希望能够在用户关闭窗口或浏览器后或连接丢失后调用清理方法吗?

1 个答案:

答案 0 :(得分:1)

当窗口关闭时,unload事件会触发,但也会在用户刷新页面或导航到新页面时触发(即使新页面位于您的站点内)。在这种情况下,我建议不要使用unload。例如,unload更适用于提示用户在离开表单之前保存或丢失更改等内容。)

另外,如果你实现了一个javascript解决方案,你要么(1)要求javascript使用该站点(并向那些禁用JS的人显示<noscript></noscript>元素),或者(2)代码使得你不是仅依靠窗口关闭/清理检测例程来释放资源。

我通常用来做这样的事情的策略是使用ping进程。基本上:客户端向服务器发送常规ping命令,当收到ping时,它会将连接/会话的idle计数器重置为0。根据需要,每分钟左右发生一次。一个长时间运行的循环线程(Session管理器,如果你愿意的话)然后检查任何闲置超过idle threshhold的客户端(比如说3分钟,但由你决定),如果超出则释放与该连接/会话相关的资源。然后,站点中的每个页面(如果适用)都会添加此ping代码,以便客户端在浏览器中打开页面时开始ping。

<强>优势

  • 跟踪用户查看您网站的时长(对指标非常有用,尤其是当与跟踪请求数量的指标结合使用时)
  • 关闭浏览器时以及当用户离开您的网站时关闭所有与连接相关的资源
  • 如果用户导航到您网站上的[具有ping代码]的不同页面,则不会清除其连接资源,因为idle计数器将在下一页重置

<强>缺点

  • 需要javascript(例如setTimeoutsetIntervalXMLHttpRequest
  • 除非您在服务器上还有类似“身份验证超时”的内容,否则如果用户离开开放式Web浏览器一段时间,客户端可能会长时间保持您的服务器(和资源)连接(您可以获得)通过使用备用ping触发器,例如鼠标移动,将焦点设置为表单字段,单击,滚动等等。

客户端页面的粗略示例代码:

function pingServer() {
  var req;
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
  } else {
    req = new ActiveXObject("Microsoft.XMLHTTP");
  }
  req.onreadystatechange = function() {
    if (req.readyState == 4 && req.status == 200) {
      alert("Idle timer reset on server");
    }
  }
  var url = 'ping.php'; // call php code that will reset idle timer for this client
  req.open("GET", url, true);
  req.send();
}
var pingFrequencyMs = 5 * 1000; // ping every 5 secs
setInterval(pingServer, pingFrequencyMs);
<noscript>Sorry, JavaScript is required for this website.</noscript>

以下是您可以在服务器端使用的一个非常粗略的流程示例,但在您提供更多详细信息之前,我只能推测您正在使用哪种Web应用程序:

服务器Ping例程(伪代码,可以是PHP,ASP,JSP等)

  1. 获取客户端连接unique ID(或会话ID,或其他)
  2. 获取客户端idle计时器的当前值,否则默认为0(可以从内存缓存,数据库,磁盘上的文件中获取;您的选择)
  3. 获取max idle(超时)
  4. 的系统值
  5. 将客户idlemax idle
  6. 进行比较
  7. 如果客户端idle超过max idle,则结束会话(无论这意味着什么;关闭连接/会话特定资源等 - 在您的情况下,这意味着调用cleanup例程,但要确保它具有正确的对象上下文),否则将idle重置为0