服务器推送事件 PHP 阻塞流程

6
我不知道是否是一个问题,但我正在使用服务器发送事件而不是ajax从php到javascript中提取内容。一切都很好,除了在服务器端休眠时,事件源会阻止网页流程。 我编写了一个相当简单的代码进行测试,并获得了相同的结果。
以下是代码:
服务器发送事件会阻塞页面流吗?它不像ajax一样执行异步请求吗?
主要问题是:服务器发送事件会阻塞代码流,我的意思是,每次事件源打开连接或接收消息时,页面都需要等待EventSource来保持代码执行。当我在服务器端代码上放置一个睡眠时,我可以清楚地看到这一点,我的页面会停止睡眠时间,运行3秒钟,然后再次崩溃。 当我进行ajax调用时,调用是异步的,因此即使我在服务器端放置一个睡眠,代码也会在后台与ajax一起运行。
以下是test.php:
                    @set_time_limit(0);
                    //send the proper header
                    header('Content-Type: text/event-stream');
                    header('Cache-Control: no-cache');
                    if(function_exists('apache_setenv')){
                        @apache_setenv('no-gzip',1);
                    }
                    @ini_set('zlib.output_compression',0);
                    @ini_set('implicit_flush',1);
                    for($i = 0; $i < ob_get_level(); $i++){
                        ob_end_flush();
                    }
                    ob_implicit_flush(1);

                $startedAt = time();

                do {

              $time = time();
              echo "id: $startedAt " . PHP_EOL;
              echo "data: {\n";
              echo "data: \"msg\": \"$time\", \n";
              echo "data: \"id\": $startedAt\n";
              echo "data: }\n";
              echo PHP_EOL;
                //@ob_flush();
                @ob_end_flush();
                @flush();   
                usleep(0.5*1000000);
                } while(true);

HTML

if(!!window.EventSource) {
     var source = new EventSource('test.php');
     source.addEventListener('open', function(event) {
     console.log('open');
  }, false);
    source.addEventListener('message', function(event) {
    var data = JSON.parse(event.data);  
    console.log(event.data);
  },false);
}

请问您能否重新表述您的具体问题? - Cobra_Fast
3
只是为了记录,我已经找到了问题。我的问题在于会话锁定PHP无法运行。 使用session_write_close()解决了问题; - Daniel Echizen
1个回答

9

正如Daniel自己回答的那样,问题可能出在会话锁定上。

session_write_close(); 

这也解决了我的问题。


谢谢您的帮助,我之前在使用 PHP WebSocket 时遇到了这个问题,但现在决定改用 SSE,结果忘记了这个问题。这个解决方案为我解决了连接锁定的问题! - Sascha Grindau
会话锁定:首先,如果您出于任何原因使用会话,则需要将其在流上设置为只读。如果它们是可写的,则会在其他所有地方锁定它们,因此任何页面加载都将挂起,而服务器则等待它们再次变为可写。通过调用session_write_close()轻松解决此问题。 - Avatar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接