服务器发送的事件会挂起浏览器

时间:2016-02-23 11:18:03

标签: php html5 server-sent-events

    <!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>SSE</title>
<script type="text/javascript">
    if (!!window.EventSource) {
        var source = new EventSource("sse.php");
    } else {
        alert("Your browser does not support Server-sent events! Please upgrade it!");
    }

    source.addEventListener("message", function(e) {
        console.log(e.data);
        if(e.data){
            x = document.getElementById("timer");
            x.innerHTML=e.data;
            console.log(e.data);
        }else{
            console.log(e.data);
            e.close();
        }
    }, false);

    source.addEventListener("open", function(e) {
        console.log("Connection was opened.");
    }, false);

    source.addEventListener("error", function(e) {
        console.log("Error - connection was lost."+e);
    }, false);

</script>
</head>
<body>
<div id="timer"></div>
</body>
</html>

我的服务器端代码

<?php
header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");
$lastId = 0;
while (true) {
    $data =10; 
    if ($data) {
        sendMessage($lastId, $data);
        $lastId++;
        $data--;
    }else{
        exit;
    }
}

function sendMessage($id, $data) {
    //echo "id: $id\n";
    echo "$data\n\n";
    ob_flush();
    flush();
}
?>

我的代码出了什么问题?请告诉我。

1 个答案:

答案 0 :(得分:0)

SERVER-SIDE :通常这种演示在发送每条消息之间都有睡眠。它会做什么,就像它所说的那样,在10ms(或其他东西)的空间内发送10个数据包。

因此,客户几乎可以在同一时间获得所有这些,您将看到&#34; 1&#34;在您的计时器<div>

客户端:看起来没问题。虽然看到登录到控制台的内容很有用。 (可能是10,10,9,9,......,1,1,10,10,9,9 ......永远重复 - 见下一位。)

BOTH :我认为退出时会发生的事情是套接字将关闭,浏览器会检测到并重新连接。再次给你相同的序列!

完全放弃,将服务器端代码主循环更改为:

while (true) {
    $data =10; 
    if ($data) {
        sendMessage($lastId, $data);
        $lastId++;
        $data--;
    }else{
        sendMessage($lastId, "0");
        sleep(1); //Give client time to deal with it.
        break;
    }
sleep(1);  //1 sec between messages
}

即。发送一个明确的&#34; 0&#34;告诉客户断开连接。

然后在客户端,请注意该显式密码。 (实际上我会选择&#34; END&#34;或其他东西,因为&#34; 0&#34;太容易评估为布尔值假!)

source.addEventListener("message", function(e) {
    console.log(e.data);
    if(e.data==="0")e.close();
    else if(e.data){
        x = document.getElementById("timer");
        x.innerHTML=e.data;
        }
    //else do nothing
}, false);