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

使用Server Sent Events实现来电触发浏览器自动刷新遇问题求助

解决CodeIgniter中SSE触发页面刷新失败的问题

看起来你是想通过第三方API调用后端接口时,触发前端SSE自动刷新页面,但目前POST调用api_new_call后页面没反应。核心问题是你把触发事件的POST接口和SSE长连接接口搞混了——两者是完全独立的请求,不能直接在POST接口里输出SSE数据,得通过中间存储传递信号给SSE接口,再由它通知前端。

下面是一步步的修复方案:

1. 先理清逻辑

  • 前端通过/controller/new_call_trigger建立SSE长连接,持续监听服务器的事件推送
  • 第三方POST调用api_new_call时,在服务器端标记"有新呼叫"的状态
  • SSE接口循环检查这个状态,一旦发现触发,就给前端发刷新信号

2. 修改后端CodeIgniter代码

① 处理第三方POST调用的api_new_call方法

这里我们用Session存储触发状态(如果是多服务器部署,建议换成Redis/数据库等全局存储):

public function api_new_call() {
    // 先做第三方请求合法性验证(比如token校验,防止恶意调用)
    $is_valid = $this->_check_third_party_token();
    if (!$is_valid) {
        $this->output->set_status_header(403);
        return;
    }

    // 标记"有新呼叫"的状态
    $this->session->set_userdata('new_call_triggered', true);

    // 给第三方返回成功响应
    $this->output
        ->set_content_type('application/json')
        ->set_output(json_encode(['status' => 'success']));
}

// 辅助方法:验证第三方请求的合法性(示例)
private function _check_third_party_token() {
    $token = $this->input->post('token');
    return $token === '你的第三方验证密钥';
}

② 修复SSE长连接的new_call_trigger方法

要确保响应头正确、禁用缓存,并且循环监听状态变化:

public function new_call_trigger() {
    // 关闭CodeIgniter的输出缓存和调试器
    $this->output->enable_profiler(false);
    ob_end_clean(); // 清除之前的输出缓冲,避免影响SSE

    // 设置SSE必须的响应头
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    header('Connection: keep-alive');
    header('Access-Control-Allow-Origin: *'); // 跨域时需要,根据实际情况调整

    // 取消PHP执行时间限制,让长连接一直运行
    set_time_limit(0);

    // 循环监听状态
    while (true) {
        // 检查是否有新呼叫触发
        if ($this->session->userdata('new_call_triggered')) {
            // 发送SSE事件给前端
            echo "data: new_call\n\n";
            flush(); // 立即推送内容到前端
            ob_flush();

            // 重置状态,避免重复触发
            $this->session->unset_userdata('new_call_triggered');
        }

        // 每隔2秒检查一次,降低服务器压力
        sleep(2);
    }
}

3. 优化前端JS代码(增加错误处理)

if (window.EventSource) {
    let source = new EventSource("/controller/new_call_trigger");
    
    source.onmessage = function(event) {
        if (event.data === 'new_call') {
            location.reload();
        }
    };

    // 处理SSE连接错误,自动重连
    source.onerror = function(error) {
        console.error('SSE连接出错:', error);
        setTimeout(() => {
            source = new EventSource("/controller/new_call_trigger");
        }, 3000);
    };
} else {
    alert('你的浏览器不支持Server-Sent Events,请升级浏览器后重试!');
}

4. 关键注意事项

  • 服务器配置:如果用Apache,要禁用mod_deflate压缩;如果用Nginx,需配置proxy_buffering off;和proxy_cache off;,确保SSE数据实时推送。
  • Session配置:确保CodeIgniter的Session已开启,文件存储的话要保证Session目录权限正确。
  • 调试技巧:在浏览器Network面板查看new_call_trigger请求的状态(应为200),同时在api_new_call里加日志,确认第三方是否真的触发了接口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:26:57