如何使用Ajax显示在线用户 [英] How to show online users with ajax

查看:57
本文介绍了如何使用Ajax显示在线用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的网站上实时显示所有在线用户.虽然不知道如何去做.在新用户登录后添加新用户并不难,但是我还需要删除不再登录的用户.

I'm want to show all the users that are online, in real-time on my website. Not sure how to go about this though. It can't be hard to add new users once they log in, but I'll also need to remove users that are not logged in anymore.

任何想法如何做到这一点?我应该使用jQuery检查哪些用户已注销并从列表中将其删除吗?

Any idea how to do this? Should I check with jQuery what users have loged off and remvove them from the list etc?

推荐答案

您的问题将是人们在不注销的情况下离开,他们的会话将仍然存在多长时间,直到您设置了超时时间,然后才可以处理他们的会话数据收集(实际上可能更长)

Your problem is going to be people navigating away without logging out, their session will still exist for how ever long you have the timeout set before their session data is subject to collection (actually possibly much longer)

要获得真正准确的登录者和访问站点的人数,您将需要每个客户端每隔几秒钟或几分钟向服务器发送一次心跳".在每个心跳触发器上,您都希望使在指定的时间段内未签到的所有用户过期.

To get a truly accurate count of who is logged in and visiting the site you will need each client to send a "heartbeat" to the server every few seconds or minutes. on each heartbeat trigger you would want to expire any users that have not checked in within the allotted time frame.

心跳信号可能最好至少由用户名和时间戳组成,但可以包含您要跟踪的任何信息.

The heartbeat signal would probably best consist of the username and a timestamp at a minimum, but could include any information you want to track.

当客户端向服务器发送单曲时,请检查该用户名的现有记录,如果记录已经存在,则覆盖时间戳信息,否则添加新记录.后记会删除所有尚未签入的用户条目.最好使信号比到期更频繁地发生.每30秒发出一次信号,每分钟清理一次.

When a client sends a single to the server have it check for an existing record for that username and overwrite the timestamp information if a record already exists, otherwise add a new one. Afterwords drop any user entries that have not checked in. Probably best to have the signal happen more often than the expiration. like signal every 30 seconds and clean up every minute.

(编辑,改变主意,最好以相同的顺序而不是单独地完成所有操作) 然后从活动表返回当前登录的用户,这就像SELECT * FROM table一样容易,因为该表始终是干净的.

(Edited, changed my mind, better to do it all in the same sequence instead of separately) Then return the currently logged in users from your active table which would be as easy as a SELECT * FROM table since the table will always be clean.

这是客户端库的一个简单示例,用于处理触发心跳功能并捕获结果.

Here is a light example of a client-side library to handle firing the heartbeat function and catching the results.

//Client-side parent variable declaration (simulated namespacing)
var Client = Client || {};
Client.Pulse = null; //Holds a pointer to the heartbeat timer (id)
/* If you needed to cancel the heartbeat processes you could
 * pass this variable to clearTimeout(). Calling Client.Heartbeat()
 * again would start the cycle back up.
 */

//Initial event that will kick off the chain when the DOM is ready
$(document).ready(function(){
  Client.Heartbeat(); //Initial call to the Heartbeat function
});//ready

/// Sends the heartbeat signal and retrieves the currently active user list
Client.Heartbeat = function(){
  var sUsername = 'SomeUser';
  /* Note: If you have an active session running on the server it would not be 
   * necessary to send the username since you could pull it on the backend 
   * script which would be more tamper-proof anyway. I'm just giving an
   * example of sending data to the server using the jQuery.ajax method
   * If you were storing the username to be sent from the client; this wouldn't 
   * be a good place to do it anyway
   * 
   * Remove the "data : {...}" line below to exclude sending information to the server
   * The "type : 'post'" line would not be necessary either 
   */

  $.ajax({ //Send the signal and recieve the information about active users back
    url : '/lib/server/Heartbeat.php',
    type : 'post',
    dataType : 'json',
    data : {Username : sUsername },
    success : function(jActiveUsers,sStatus,jqXHR){ 
      /* This is the callback function of the request, jActiveUsers will be the 
       * json object with the information you choose to send back to it
       */
      Client.RenderActiveUsers(jActiveUsers); //Call the display function
      //Trigger the next delayed call to Client.Heartbeat
      Client.Pulse = setTimeout(function(){
        Client.Heartbeat();
      },30000); //30 second delay before next trigger
    }//success
  });//$.ajax
}//Heartbeat

/// Processes the results sent by the server and draws them to the UI
Client.RenderActiveUsers = function(jActiveUsers){
  /* This is where you would get a handle whatever element(s) on the page
   * will be displaying the information about currently active users
   * and filling it with the list of users how ever you would wish to display it.
   */
}//RenderActiveUsers

因为在整个周期结束时您将处理异步回调setTimeout()调用以重新开始该过程,所以如果您使用setInterval()并且服务器花费了更长的时间,这将是一种更清晰的间隔处理方式超出预期的回报,您可能会看到客户端开始自我竞争.在成功的回调中使用setTimeout()还可使您在服务器端心跳处理器停止工作的情况下正常失败.客户端也将这样做,而不是继续进行失败的尝试(如果您希望它继续尝试,您只需在失败的响应上添加一个重新触发程序即可.)

Because you will be dealing with asynchronous callbacks setTimeout() calls at the end of a full cycle to start the process over again will be a cleaner way of handling the interval if you were to use setInterval() and the server took longer than expected to return you could see the client start to race on itself. Using a setTimeout() within a successful callback also allows you to fail gracefully in the event the server-side heartbeat processor stops working; so will the client side instead of continuing to make failed attempts (if you want it to keep trying you just need to add a retrigger on a failed response as well).

很抱歉,我不熟悉Java作为后端服务,我会 根据PHP的工作原理做出一些假设;因此我不能 确保它将直接映射到您的环境. 数据库示例将使用MySQL. 代码示例将是伪伪造的PHP(ish)

I apologize I am not familiar with Java as a back-end service, I will be making some assumptions based on how PHP works; so I cannot guarantee it will map directly to your environment. Database examples will assume MySQL. code examples will be pseudo-cody PHP(ish)

在服务器端,您将需要一个新表来跟踪活动用户.当他们登录数据库时,您可能已经在跟踪它们了,但这将与该系统分开(尽管您当然可以链接到该系统,以获得有关返回结构的更多用户详细信息)

On the server end of it you will need a new table for tracking the active users. You will possibly already be tracking when they log in within the database but this would be separate from that system (though you could of course link to it to get extra user details for your return structure)

该表将至少显示以下内容:

The table would look at a minimum something like:

 ActiveUsers
 -----------------------------------------
 |   Field    |    Type     | NULL | Key |
 -----------------------------------------
 | Id         | int         |      | PRI |
 | Username   | varchar(xx) |      |     |
 | LastPulse  | datetime    |      |     |
 | FirstPulse | datetime    |      |     |
 -----------------------------------------

(推测)我假设像PHP一样,Java中也有Sessions,您可以用来存储有关特定访问者的信息(例如其当前状态).在PHP中,这是通过在客户端和服务器之间来回传递标识符来实现的,允许服务器识别特定的客户端,并在后端为您存储与该会话相关的变量(例如,具有当前登录状态的布尔值用户名或一个字符串,用于在登录后保留其用户名.)

(speculation) I'm assuming that like PHP there are Sessions in Java which you can use to store information about a particular visitor like their current status. In PHP this works by passing an identifier back and forth between the client and server, allowing the server to identify a particular client and for you on the back-end to store variables related to that session (For instance a boolean with the current login state of the user, or a string to hold their username once logged in.)

如果您可以使用此方法,那将是一种比身份验证存储客户端安全得多的方法,该方法比在客户端存储此信息并允许客户端指示是否以及谁登录的身份更为重要.在此假设它是...

If this is available to you it would be a much more secure way to handle authentication than to store this information client-side and allow the client to indicate if and as who it is logged in. Herein assuming it is....

当客户端将心跳发送到服务器时,如果它们实际上已登录,则可以从会话变量访问其登录状态和用户名,以开始该过程.

When the client sends the heartbeat to the server you can access their logged in state and username from the session variables if they are in-fact logged in to begin the process.

if($LoggedIn && ($Username != null)){ //Session information

如果未登录,则由于无需为它们添加或修改记录,您将跳至列表检索部分

If they are not logged in you would skip down to the list retrieval part since you won't need to add or modify a record for them

检查它们是否在活动表中有记录

Check if they have a record in the active table

SELECT `Id` FROM `ActiveUsers` WHERE `Username` = '{$Username}' LIMIT 1

如果有记录,则表示它们已经签入过,并且您想使用从第一个查询返回的ID值以新的时间戳更新记录

If a record exists it means they have already checked in before and you want to update the record with a new timestamp using the Id value returned from the first query

UPDATE `ActiveUsers` SET `LastPulse` = NOW() WHERE `Id` = {$Id}

如果不存在任何记录,您将改为为此用户创建一个新记录

If no record exists you will want to make a new one for this user instead

INSERT INTO `ActiveUsers` (`Username`,`LastPulse`,`FirstPulse`) VALUES ('{$Username}',NOW(),NOW()) 

接下来是该过程的维护阶段,在该阶段中,您将在您要设置为限制的时间(此示例中为2分钟)内清除所有未检入的条目.

Next comes the maintenance phase of the process where you clean up any entries that have not checked in with in the amount of time you want to set as the limit (2 minutes in this example)

DELETE FROM `ActiveUsers` WHERE `LastPulse` < (NOW() - INTERVAL 2 MINUTE)

这将离开您的ActiveUsers表,以便仅存在活动用户的记录,您现在可以查询获取这些记录,以及您希望从此表和任何其他表链接到的其他信息

This will leave your ActiveUsers table so that only records for active users exist which you can now query against to get, along with any other information you want from this and any other table you can link to

SELECT `Username`, UNIX_TIMESTAMP(`FirstPulse`) AS `FirstPulse` FROM `ActiveUsers` ORDER BY `FirstPulse` ASC

(在PHP中)然后,您需要遍历结果集并构建一个用户数组,该用户数组将通过调用json_encode()print() ed以及"application/json"标头值,以便jQuery可以正确处理它.当然,这在Java实现上会有所不同,但是创建数组,将其转换为JSON字符串并使用指定的适当标头将其打印出来"的整个过程将是相同的.

(In PHP) You would then need to loop over the result set and build an array of users which would be converted to JSON with a call to json_encode() and print()ed along with an "application/json" header value so that jQuery can process it properly. This will of course differ between Java in implementation but the overall process of "create an array, convert it to a JSON string and print it out with a proper header specified" will be the same.

理想情况下,对于任何类型的身份验证过程,您都希望将客户端保持为哑" .在此示例中,客户端只是通过请求新的活动用户列表来盲目地与服务器签入并触发清除过期的用户.

Ideally you want to keep the client as "dumb" as possible to any type of authentication process. In this example the client is blindly checking in with the server and triggering a cleanup of expired users just by asking for a new list of the active users.

如果在一个利用率很高的站点上,100%准确的列表对于任务至关重要,则可能有必要在执行维护部分时锁定桌子.以确保在另一个线程处于检入阶段时不会查询用户列表.

If a 100% accurate list is mission-critical on a highly utilized site it may be necessary to lock the table while performing the maintenance portions. to ensure no queries for the user list occur while another thread is in the check-in phase.

(哇,这变成了Wall-O-Text)

这篇关于如何使用Ajax显示在线用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆