You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery AJAX.done()执行正常但阻塞聊天消息拉取功能,该如何解决?

问题原因
  1. 核心诱因是PHP会话(Session)锁定:PHP默认使用文件存储Session,同一个客户端发起的同Session请求会被服务端排队,第一个请求会锁定Session文件,后续同Session的请求必须等前一个请求执行完毕释放锁后才能执行。你的chat-mail.php执行发邮件逻辑需要5-10秒,全程持有Session锁,导致同期的get-chat.php拉取请求全部被阻塞在服务端排队,看起来就像前端定时任务被卡住。
  2. 次要原因是浏览器同域名并发请求限制:主流浏览器对同一个域名的并发请求数限制通常为6-8个,长耗时的发邮件请求占住连接后,也可能导致后续拉取请求被浏览器端排队。
解决方案

按照改造成本和生效速度排序如下:

1. 提前释放会话锁(改造成本最低,立即生效)

在不需要操作Session的脚本开头提前释放Session锁即可:

  • chat-mail.php全程没有用到Session操作,直接在代码第一行加session_write_close();,脚本拿到请求参数后立即释放Session锁,后续拉取聊天的请求不会再被阻塞。
  • chat.php在完成Session相关操作(比如你用到的sessionUser()是读Session逻辑)后,也可以提前调用session_write_close(),再执行后续的数据库查询、返回响应逻辑。

示例代码(chat-mail.php开头新增):

<?php
session_write_close(); // 新增行,提前释放Session锁
// 原有代码不变
$name  = (!empty($_POST['name']))?$_POST['name']:null;
$email = (!empty($_POST['email']))?$_POST['email']:null;
// ...

2. 异步队列处理邮件(彻底解决问题,长期最优)

不要让前端请求同步等待邮件发送,把邮件逻辑改成后台异步执行:

  • 新增邮件任务表,字段包含收件人邮箱、邮件标题、邮件内容、发送状态、创建时间即可。
  • chat.php判断需要发邮件时,直接把邮件参数插入任务表,立即返回接口响应,不需要等待邮件发送。
  • 配置crontab定时任务,每分钟执行一次脚本消费任务表中的待发送邮件,后台异步完成发送。

3. 前端体验优化

  • 发送消息成功后直接在前端拼接消息到聊天框,不需要等待定时拉取,用户可以立即看到自己发送的内容,完全规避等待问题:
success: function(json){
  inputField.val('');
  // 主动拼接自己发送的消息,不用等拉取返回
  const myMsg = `<div class="outgoing-msg">${inputField.val()}</div>`;
  chatBox.append(myMsg);
  $('html,body').animate({scrollTop: document.body.scrollHeight}, "fast");
}
  • 优化定时拉取逻辑,避免请求堆积:每次拉取请求完成后再发起下一次,而不是固定500ms发一次,避免网络差时请求堆积占满并发数:
let isLoadingChat = false;
function getChat() {
  if (isLoadingChat) return;
  isLoadingChat = true;
  $.ajax({
    // 原有请求配置不变
    complete: function() {
      isLoadingChat = false;
      setTimeout(getChat, 500);
    }
  })
}
getChat(); // 初始化调用替代原setInterval

内容的提问来源于stack exchange,提问作者Relaxing Music

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 22:27:02