使用PHP实现服务器推送事件

3

我有一个Web应用程序,它从JS脚本发送一些数据到PHP服务器,然后将其插入到MySQL数据库中。我还需要通知所有其他客户端已经发送了数据并将其发送给他们。

我正在尝试使用Server-Sent Events来完成此操作,但我对概念有些困惑。这是我的代码:

$(document).ready(function() {
    var source = new EventSource("../Server/insertMessage.php");
    if(typeof(EventSource) == "undefined") {
        alert("event source doesnt work");
    } else { alert("event source works"); }

    source.onmessage = function(event) {
        alert(event.data);
        // do stuff with event.data
    };
});

在我的js脚本中,我向insertMessage.php发送一个带有POST参数的AJAX请求作为数据细节。这会触发服务器端事件吗?以下是我的服务器端代码:

insertMessage.php

if(isset(// check POST to see if the right request was sent)) {
    // insert data into database
    // ...
    // ...

    // Send the new data to listeners
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    // Create data array
    $dataArray = array("data" => $data, "moreData" => $moreData);
    // Encode JSON
    $callback = json_encode($dataArray);
    // Send it
    echo "data: $callback";
    flush();
}

当“事件源正常工作”警报被发送时,即使我正在调用insertMessage.php进行AJAX调用,我也从未收到event.data警报。也许我还没有完全理解服务器推送事件。我做错了什么?


1
你可能想了解Node.js和Web套接字。PHP无法启动任何连接,客户端必须连接到服务器。 - Charlotte Dunois
@CharlotteDunois 但我并没有使用PHP来初始化任何连接。我只是在尝试在事件发生时从服务器向客户端发送一些数据。我不完全确定我是否正确地从服务器触发了该事件。 - Youssef Moawad
1
你需要使用Node.js和Web Sockets来完成。PHP无法实现你的需求。 - Charlotte Dunois
@CharlotteDunois,您能否详细说明我该如何做到这一点? - Youssef Moawad
@CharlotteDunois 在这方面完全正确。你想做的是从服务器向客户端 push 数据。如果客户端与服务器之间没有活动连接,这是无法完成的。你应该寻找的技术最好是 推送通知 或者 websockets。你也可以使用 AJAX,但它很棘手,需要每隔 N 秒向服务器发送请求以 "检查" 新数据。 - tftd
2个回答

3

您不能以这种方式使用服务器发送事件:

请使用以下方式:

session_write_close(); // Close the session before your response! It helps your client create new requests to you server during the execution.

$echo= "id: $time" . PHP_EOL; // Important!
$echo.= "retry: ".$retry_time."" . PHP_EOL;  // Handle reconnect time (ms)
$echo.= "event: message" . PHP_EOL; // Event message type
$echo.= "data: {\n"; // JSON
$echo.= "data: \"data\": \"$data\" \n";  // JSON
$echo.= "data: }\n"; // JSON
$echo.= PHP_EOL; // Important!

在Eventsource中,换行非常重要!

你可以使用PHP进行SSE,但始终记住,在执行期间应尽快关闭SESSION!

我的压力测试结果:(服务器配置:4核@2.3Ghz,8Gb RAM,100/100Mbit)Ubuntu 14.04 + Apache,最大连接数:1024

100个连接负载=0.14,每秒刷新1次和1个SQL查询/时刻。

在500-600活跃用户以下,即使使用Apache,你都可以毫无问题地使用PHP进行SSE。


0
这个不起作用的原因是因为当你的JavaScript正在创建EventSource或执行HTTP GET时。所以你的PHP代码没有返回任何东西。你不能使用EventSource进行POST请求。

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