为什么我在使用 js 服务器使用 php 发送事件时看到未指定的 sse 错误?

问题描述 投票:0回答:2

我正在设置一个系统,在其中使用 JS Server-Sent_Events 和 php。 而且效果很好。但每次都会触发错误事件一次,我不明白为什么。

我的JS:

var source = new EventSource("serverSideEvents.php");
source.onmessage = function(event) {
     var data =  $.parseJSON(event.data);
     $(data).each(function(){
            doSomethingWith(this); //works as expected
      });
};

source.onerror = function(event) {
   console.log(event); //fires every few seconds don't know why
};

我的PHP:

<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache'); 

  sendUpdates( );

function sendUpdates() {
  $controller = new someController();
  $out = $controller->Run();
  foreach($out as $msg)
    sendSSEMessage($msg['id'], 'data:'.json_encode($msg));
}

function sendSSEMessage( $id, $data ){
  echo "id: $id \n$data \n\n";
  ob_flush();
  flush();
}

这工作正常,在 cli 或浏览器上,php 不会抛出任何错误,但每次运行 php 时都会触发 js SSE 的错误事件。这是控制台中出现的错误:

Event {isTrusted: true, type: "error", target: EventSource, currentTarget: EventSource, eventPhase: 2, …}
bubbles:false
cancelBubble:false
cancelable:false
composed:false
currentTarget:
EventSource {url: "http://localhost:7790/serverSideEvents.php", withCredentials: false, readyState: 0, onopen: null, onmessage: ƒ, …}
defaultPrevented:false
eventPhase:0
isTrusted:true
path:[]
returnValue:true
srcElement:EventSource {url: "http://localhost:7790/serverSideEvents.php", withCredentials: false, readyState: 0, onopen: null, onmessage: ƒ, …}
target:EventSource {url: "http://localhost:7790/serverSideEvents.php", withCredentials: false, readyState: 0, onopen: null, onmessage: ƒ, …}
timeStamp:1129162.5250000001
type:"error"
__proto__:Event

需要明确的是:代码按预期工作。我收到了我需要的服务器消息。但也会触发错误事件。

javascript php server-sent-events
2个回答
0
投票

该错误通常是由于服务器错误并关闭连接而发生,或者当服务器简单地关闭连接时(发生在服务器脚本完成时),

我认为正确的方法是关闭客户端的连接,

所以在我的客户中我正在做:

<script>
    // Open a new EventSource connection to the SSE server
    const eventSource = new EventSource('/My_SSE_URL');
                
    // Event listener for messages received from the SSE server
    eventSource.onmessage = function (event) {
        // Handle received event message
    };
    
    eventSource.onerror = function(error) {
        // Close the connection in case of an error
        eventSource.close(); // <---- This is what you want to do
    
        console.error('Error occurred:', error);
        // Handle the SSE connection error as needed
        // For example, you can display an error message to the user
    };
</script>

-1
投票

好的,谢谢 站点点。 每次服务器关闭连接时都会触发错误事件,每当脚本终止时都会发生这种情况。然后浏览器会再次尝试。

因此,为了防止这种情况,我们必须通过将 php 发送到一个循环中来保持它的活动状态,并最终让服务器根据 php.ini 中的 max_run_time 终止它,或者在定义的重新运行次数后自行终止它。 这样做可能有助于减少浏览器重新连接时发生的开销。但请注意,运行脚本(无论是否处于睡眠状态)都会给服务器负载带来负担。因此,如果您有很多连接,这可能是不可取的。

当然我们也可以简单地忽略该错误。

© www.soinside.com 2019 - 2024. All rights reserved.