在javascript中卸载之前关闭服务器端聊天连接

时间:2014-02-14 21:36:03

标签: javascript php mysql ajax session

在我的网站上,我建了一个支持多个房间的聊天室。当用户加入会议室时,会话将被放入数据库中,这样如果他们再次尝试在另一个浏览器窗口中加入会议室,则会被锁定。

它像这样工作

1. Join the chatroom page
2. Connect to chatroom #main
If the user has a session in the database for #main
--- Block user from joining
else
--- Load chatroom

当聊天室关闭时,客户端或用户终止与/ quit命令的连接,所有会话都被删除,这样可以正常工作。

然而
用户可能只关闭浏览器窗口而不是终止其连接。这个问题是他们的会话将保留在数据库中,这意味着当他们尝试连接到房间时,他们会被阻止。

我正在使用此代码onbeforeunload来尝试阻止

function disconnect() {
        $.ajax({
            url: "/remove-chat-sessions.php?global",
            async: false
        });
};

这也是用户键入/ quit命令时调用的函数

问题
这样做的问题是,当我重新加载页面时,10次会话中的5次没有从数据库中取出,好像ajax请求失败或页面在完成之前重新加载。这意味着当我回到聊天室时,数据库仍然认为我已连接,并阻止我进入聊天室

有没有更好的方法来确保加载此AJAX调用,如果没有,是否有比在线数据库中存储用户会话更好的选择?

修改
阻止用户多次加入会议室的原因是因为当聊天室更新新邮件时,您发布的邮件不会显示给您。当您发布它们时,它们会附加到聊天室框中。这意味着如果用户可以在多个窗口中的同一个聊天室中,他们将无法看到他们在所有窗口中发布的评论。

1 个答案:

答案 0 :(得分:0)

在这种情况下,您可以添加某种轮询。基本上,你每隔X次就用javascript请求一个页面。该页面将用户会话添加到数据库。然后每隔Y时间执行一个脚本,其中Y> X,清理旧会话。

每X次调用的脚本

...
// DB call (do as you like)
$All = fetch_all_recent();
foreach ($All as $Session)
  {
  if ($Session['time'] < time() - $y)
    {
    delete_session($Session['id']);
    }
  }

javascript每X次调用的脚本

...
delete_old_session($User->id);
add_user_session($User->id, $Chat->id, time());

这种方法的主要缺点是请求的增加,这是Apache不习惯的(对于大的请求号)。对此有两种非排他性的替代方案,包括访问服务器,是:

  1. 使用nginx server。我没有这方面的经验,但我读过它支持比Apache更多的连接。

  2. 使用一些现代形式的持久连接,例如socket.io。但是,它使用node.js,这可能是好的也可能是坏的,具体取决于您的业务。