2013-03-11 135 views
1

我正在创建一个简单的实时聊天应用程序,所以我必须在页面的右侧显示chatBuddyList。 (user_id,name,email ...)和tbl_logged_user(id,user_id)。获取登录用户列表PHP

用户登录我会将user_id添加到tbl_logged_users并在注销时删除该记录。

一切都很好,但问题是与Logout。当用户点击logout链接它将工作,但有时用户可能会自动注销,由于会话到期,浏览器关闭等...

我该如何处理这种情况?什么是实现这一目标的最佳方式?

谢谢。

我想找到最好的方法,只是因为确切的应用程序不是一个真正的聊天基础之一,我有一个表/ s与平均80,000记录。投票/彗星运行时间约5-10秒。

编辑

有一些答案说关于session_id。我相信它没有用,因为会话超时PHP不能自动更新数据库表,除非有新的请求。

+0

我以前做过这个。为了解决这个问题,有必要在数据库中写入与客户端最近一次联系的时间戳,并测试它是否早于x秒。 – fnkr 2013-03-11 09:37:28

+0

@fnkr“闲置”用户呢。 – Red 2013-03-11 09:43:20

+0

你可以实现[SessionHandlerInterface](http://php.net/manual/en/class.sessionhandlerinterface.php)。在你的[destroy](http://php.net/manual/en/sessionhandlerinterface.destroy.php)方法中,你可以使用session_id()更新数据库。 – mend3 2017-10-31 11:42:27

回答

2

那么,这不是解决问题的“常用”方式,但我认为这不是一个糟糕的解决方案:

您可以使用带有小型Node.js serv的websocket呃例如。当用户使用有效的会话加载页面时,它会连接到服务器(只有两行javascript)。当它断开连接(关闭页面)时,websocket消除并且服务器捕获事件。

如果用户关闭浏览器,则套接字断开连接。如果用户单击注销,则页面重新加载,然后不再创建套接字(无效会话)。唯一的问题出现在用户长时间打开浏览器并且会话过期时。那么,在服务器中添加超时将解决此问题。

如果你正在创建一个聊天应用程序,试试websockets,你不会后悔。

+0

感谢蛮力,我想避免这样的事情,只是因为我没有意识到这一点。让我想一想'Node.js'。 – Red 2013-03-11 10:40:36

+0

那么,你会喜欢node.js =)另外检查出Socket.IO http://socket.io/ – TheBronx 2013-03-11 10:49:53

0

考虑一个用户登录,如果他在最近5分钟内(或左右)处于活动状态。几乎每个网站都是这样处理的。 您可以在用户每次“做”什么时间(即在客舱发送邮件)

+0

感谢您的想法,但它是聊天应用程序的情况下可靠的方式?例如:假设有3个用户。 'User1'和'User2'互相聊天,'User3'是'idle',这三个人可以在chatList上看到3个用户,现在'User3'在会话超时时间内被注销,我该如何处理?任何想法? – Red 2013-03-11 09:42:53

+0

如果Ajax刷新自上次时间戳更新后超过4分钟,您可以再次更新时间戳。 – 2013-03-11 09:49:38

+0

没有防水的方式来注册它。如果您每隔几秒钟在网络服务器上“轮询”新邮件(使用ajax),则可以将您的超时设置为@ 30秒,例如 – 2013-03-11 09:50:49

-1

只是注册一个时间戳,如果你保持一个表的会议,仅计算表活动会话的数量。

+0

你能多解释一下吗? (我希望这是一个答案) – Red 2013-03-11 09:46:10

+1

会话表不可靠。当用户关闭他的窗口时,会话表将不会更新,直到您将会话“终止”(例如,使用PHP的默认超时) – 2013-03-11 09:49:46

+0

您正在使用框架吗?你的课程去哪里?在文件系统或数据库?如果它是一个文件系统,你可以做$ sessionCount = count(glob(session_save_path()。“/ *”)); – priyolahiri 2013-03-11 09:50:35

1

在登录时将会话标识存储在表中,并定期检查会话标识,以便状态用户处于联机状态,如果用户关闭浏览器会话标识则不会匹配,然后注销用户。

+0

你能解释一下吗?如何检查session_id? – 2014-03-17 19:59:25

2

这是我的聊天应用程序中的会话检查器代码。
$ CONFIG [“app:maxLatency”]是以秒为单位的时间。在此之后,如果客户没有联系服务器,客户端将被注销。
你需要一个叫做用户ID(整数),lastseen(时间戳)和SID

样品台表(会话ID,文本):

id  | lastseen    | sid 
-------------------------------------------------- 
123 | 2013-03-11 11:00:00  | abcdefg12345 

示例代码:

function DeleteSessionByUserId($user_id) { 
    $user_id = mysql_real_escape_string($user_id); 
    global $CONFIG; 

    $sql = "UPDATE users SET sid = '' WHERE id = '".$user_id."'"; 
    $result = mysql_query($sql); 
    return true; 
} 

// This will delete all users with expired sessions 
function CheckAllSessionsExpired() { 
    global $CONFIG; 

    $sql = "SELECT id FROM users WHERE sid != '' AND lastseen < '".date("Y-m-d H:i:s", strtotime("-".$CONFIG["app:maxLatency"]." seconds"))."'"; 

    $result = mysql_query($sql); 
    while ($line = mysql_fetch_array($result, MYSQL_ASSOC)) { 
     DeleteSessionByUserId($line['id']); 
    } 
    return true; 
} 

// This will update the last seen timestamp in MySQL 
function UserSetSeen($user_id) { 
    $user_id = mysql_real_escape_string($user_id); 

    global $CONFIG; 
    $sql = "UPDATE users SET lastseen = '".date("Y-m-d H:i:s")."' WHERE id = '".$user_id."';"; 
    $result = mysql_query($sql); 
    return true; 
} 
+1

'CheckAllSessionsExpired'会杀死我所有的闲置用户。 – Red 2013-03-11 10:03:40

+0

您是否每次客户端与服务器联系时都运行UserSetSeen($ user_id)?我使用JavaScript来每隔1秒刷新一次消息。 – fnkr 2013-03-11 10:04:57

+0

感谢您的努力,技术上它的确定。但在我的情况下,它不实用,只是想想互联网连接丢失,所以它将无法更新'时间戳',也不能在页面上运行超过2次民意调查。 – Red 2013-03-11 10:10:21