Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中卸载之前关闭服务器端聊天连接_Javascript_Php_Mysql_Ajax_Session - Fatal编程技术网

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

在javascript中卸载之前关闭服务器端聊天连接,javascript,php,mysql,ajax,session,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 当

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

它是这样工作的

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命令终止连接时,他们的所有会话都会被删除,这样就可以正常工作

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

我在卸载前使用此代码来尝试阻止这种情况

function disconnect() {
        $.ajax({
            url: "/remove-chat-sessions.php?global",
            async: false
        });
};
这也是用户键入/quit命令时调用的函数

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

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

编辑:

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

在这种情况下,您可以添加某种轮询。基本上,每X次使用javascript请求一个页面。该页面将用户会话添加到数据库中。然后每次都有一个脚本执行,其中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']);
    }
  }
...
delete_old_session($User->id);
add_user_session($User->id, $Chat->id, time());
这种方法的主要缺点是请求量的增加,这是Apache不太习惯的(对于大量请求)。有两种非排他性的替代方案,涉及对服务器的访问,它们是:

  • 使用。我没有这方面的经验,但我读到它支持比Apache更多的连接

  • 使用一些现代形式的持久连接,如。但是,它使用node.js,它可以是好的也可以是坏的,这取决于您的业务


  • 也许您不应该在加入新会话时阻止它们,而应该使旧会话无效并使用新会话。@JonathanKuhn,阻止它们的原因是您发布的消息不会出现在聊天室中。当你发布它们时,它们就会出现。这意味着,如果用户可以在多个窗口的同一聊天室中,他们将无法看到他们在所有窗口发布的评论。因此,假设您有一个每隔几秒钟检查一次新消息的轮询。当它进行轮询时,让它检查表中的会话是否与请求的会话匹配。如果它们不匹配,则返回一条消息,说明“您已断开连接,因为您已登录到另一个窗口”,并停止轮询。然后只在他们加入/离开房间时在表中设置会话,而不是在投票中。阅读评论和编辑后,我认为你基本上在某个地方有问题,并尝试以完全不同的方式解决它。虽然我的回答对原来的问题是正确的,但我建议您改写整个问题以解决您的特定问题。根据我的经验,nginx比apache更好地处理静态页面/内容,而apache更好地处理动态内容,如php。不管怎样,这只是一个观点,并不需要回答这个问题。这帮助我继续我需要做的事情,谢谢。