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

标签 javascript php mysql ajax session

在我的网站上,我建立了一个支持多个房间的聊天室。当用户加入房间时, 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 命令终止连接时,所有 session 都将被删除,这可以正常工作。

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

我在 onbeforeunload 中使用此代码来尝试阻止这种情况

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

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

问题
这样做的问题是,当我重新加载页面时,十分之五的 session 尚未从数据库中取出,就好像 ajax 请求失败或页面在完成之前重新加载一样。这意味着当我返回聊天室时,数据库仍然认为我已连接,并阻止我进入聊天室

是否有更好的方法来确保加载此 AJAX 调用,如果没有,是否有比将用户 session 存储在在线数据库中更好的替代方案?

编辑:
用户多次被阻止加入聊天室的原因是,当聊天室更新新消息时,您发布的消息不会出现在您面前。当您发布它们时,它们会附加到聊天室框中。这意味着,如果用户可以在多个窗口上位于同一个聊天室中,他们将无法看到他们在所有窗口上发布的评论。

最佳答案

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

每 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,这可能是好是坏,具体取决于您的业务。

关于javascript - 在 JavaScript 中卸载之前关闭服务器端聊天连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21789927/

相关文章:

javascript - 如何在网站中做向导?

javascript - 替换 JavaScript 中 URL 字符串中的特定值

javascript - 如何根据数据库用户 ID(不是 uid)设置 firebase 规则

php - 在PHP中用单个逗号删除多个逗号

php - 使用高级php上传图片

mysql - Codeigniter 迁移 + 多个表 + 每个表一个迁移文件

javascript - 如何使用 jQuery 在当前选定行下方添加一行(基于下拉输入)?

php - 使用 php 从非公共(public) html 文件夹下载文件

mysql - 保持 MySQL 模式在计算机之间同步

MySQL计算多个用户之间的共同 friend