检测Live Server端更改(长轮询,短轮询或Web套接字)

时间:2013-05-13 17:05:27

标签: php javascript jquery websocket long-polling

理由与研究

我有一个网站要求用户登录才能查看。用户登录后,我想留意他们的用户会话。通过这个,我的意思是我想知道他们的用户会话是否已经过期,因此重定向他们。

每个用户的会话持续1小时(或我设置的任何会话),如果他们访问不同的页面(如大多数登录系统),则会重置。

目前,我有以下算法:

  1. 用户到达私人页面(名为isUserAuthorized()的javascript方法已执行)
  2. isUserAuthorized() javascript方法向页面'ajax.example.net/authorized'发出AJAX请求
  3. 此页面返回一个JSON对象,指示用户的当前状态,如下所示:
  4. { authorized: true, timeout: 3600000 }

    1. javascript方法然后设置超时以在timeout毫秒内再次调用该方法,假设会话将结束。
    2. 如果会话已结束,则重定向用户,否则在timeout毫秒内在方法中调用。
    3. 我不喜欢这种当前的方法有两个原因:

      1. 我遇到了客户端和服务器时钟之间的时间同步问题,这很奇怪,但肯定会导致问题......
      2. 它在网页的背景中留下了超时,并且由于这个网站非常重要,我宁愿没有这个额外的超时,以保持网站尽可能顺利。
      3. 我的问题

        因此,我的问题是,有人能想出更好的方法吗?我想过长轮询或websockets,但我不是100%肯定如何使用这些和我发现的websockets上的教程不是很好!这些实际上是一个更好的解决方案吗?

        我可以解决时间同步问题,但在此之前,我想确保没有更好的方法来实现这一目标......

        如果有帮助,这是我当前的代码:

        // Set the Authorized Timeout
        MN.authorizedTimeout = setTimeout(function(){MN.isUserAuthorized});
        
        /**
         * Is User Authorized
         * Checks to see if the current user is authorized and
         * makes sure their session is still active
         */
        MN.isUserAuthorized = isUserAuthorized;
        function isUserAuthorized(){
            // TEMPORARY
            console.log('authorising');
            // Set the authorized var
            var authorized = false;
            // Clear the current timeout
            clearTimeout(MN.authorizedTimeout);
            // Send request to determine whether the user is authorized
            $.ajax({
                url: "//ajax.example.net/authorized",
                type: "GET",
                dataType: "JSON",
                cache: false,
                async: false,
                success: function(data){
                    console.log(data);
                    if(data.authorized){
                        // If the user is authorized then check again in timeout milliseconds
                        MN.authorizedTimeout = setTimeout(MN.isUserAuthorized,data.timeout_milliseconds);
                        // Set authorized to true
                        authorized = true;
                    }else{
                        // If the session has expired then proceed to informing the user
                        MN.userSessionExpired();
                        // Set authorized to false
                        authorized = false;
                    }
                }
            });
            // Return the session status boolean
            return authorized;
        }
        

2 个答案:

答案 0 :(得分:1)

更新答案:

尽管如此,我认为计算在线状态服务器端是一种更好的做法。所以你可以确保时间没有不一致。你只有你的servertime。

要获得在线状态,您可以进行长时间的轮询。我给你举了一个例子:

(function checkLoginStatus(){
    $.ajax({ 
      type: 'POST',
      url: 'loginstatus.php',
      data: {userid : 25},
      success: function(data){
        if(data.logged_in !== true){
          //Log the user out
        }
      }, 
      dataType: "json", 
      complete: checkLoginStatus, 
      timeout: 15000 
    });
})();

这将确保仅在15秒过去和请求完成时才发出新请求。

旧答案:

如果您唯一需要关注的是登录用户,则无需轮询。我会将整个服务器保留在服务器上。只需在用户表中添加“last_active”字段即可。

每当用户进行交互(访问另一个站点)时,都会将时间戳更新为当前时间戳。

要检测用户是否在线,请使用当前时间戳并从中减去“last_active”时间戳。如果差异大于一小时,则表示您的用户处于非活动状态。

这就是我经常处理它的方式。它(也就是资源)比做它更有效 用AJAX。

答案 1 :(得分:1)

在大图中,您希望服务器上的某些内容会在用户会话到期时提醒前端。

长轮询可以做到这一点。基本上你会有一个后端控制器接受连接并保持它们,直到它收到发送响应的信号,或连接超时。因此,您的前端将有一个基本上发送请求并等待响应的循环。如果响应返回空,则为超时,因此请发送新请求。如果响应有内容,则不是超时,因此您可以采取措施。这实现了您的目标,许多此类系统都是以这种方式构建的。但是,反向使用HTTP是一种破解,而不是干净的代码。

websocket是客户端和服务器之间的双向接口。这是你的客户端js的样子。

  function connect(){
    websocket = new WebSocket("wss://yoursite.com:8080");
    //attach event handlers
    websocket.onmessage = onMessage;
  }
  function onMessage(evt){
    // do your thing
  }

致电connect()后,您可以放心,onMessage()会在服务器需要到达客户端时照顾您。对我而言,从服务器向客户端发送消息正是我们拥有websockets的原因,因此它们是适合这项工作的工具。