JavaScript,PHP - 使用服务器发送的事件与多个唯一用户?

Bir*_*rel 5 javascript php server-sent-events

我对SSE来说是全新的.服务器发送事件有很多简单/介绍性文本

但他们都没有涉及为多个不同的用户使用相同的SSE文件.

例如:

我有一个用户登录的站点.登录后,他们可以查看对他们来说唯一且私有的数据.我希望每个用户在登录时都有实时更新,这些更新可能包含也可能不包含敏感信息.为此,我正在实现服务器发送的事件:

JS(直接从其中一个链接)

var source;

if (!!window.EventSource) {
    source = new EventSource("sse.php");
} else {
    ...
}

source.addEventListener("message", function(e) {
    ... do stuff ...
}, false);
Run Code Online (Sandbox Code Playgroud)

PHP

header("Content-Type: text/event-stream");
header("Cache-Control: no-cache");
header("Connection: keep-alive");

while (true) {
    $data = \\ query DB or any other source
    if ($data) {
        sendMessage($someID, $data);
    }
    sleep(2);
}

function sendMessage($id, $data) {
    echo "id: $id\n";
    echo "data: $data\n\n";
    ob_flush();
    flush();
}
Run Code Online (Sandbox Code Playgroud)

但是这样使用它,我只是将数据发送给打开sse.php源的用户(即每个EventSource("sse.php")都是一个新的,唯一的连接)?或者每个人都登录,谁初始化了连接,收到相同的数据?

这个SO答案通过使用独特的事件触及多个用户:

echo "event: ping\n";
$msg1="This is first user";
echo 'data: {"msg": "' . $msg1 . '"}';
echo "\n\n";

echo "event: notify\n";
$msg2="This is second user";
echo 'data: {"msg": "' . $msg2 . '"}';
echo "\n\n";
Run Code Online (Sandbox Code Playgroud)

然后只听一个特定的事件:

var evtSource = new EventSource("sender.php");
evtSource.addEventListener("ping", function(e) {
var obj = JSON.parse(e.data);
var r_msg = obj.msg;
Run Code Online (Sandbox Code Playgroud)

但这似乎不合理.如果每个用户都应该接收他们自己的私人订阅源,那么这种方法将要求我为每个用户硬编码一个唯一的事件.并且,正如最初的答案所提到的,它不会阻止略高于平均水平的用户拦截和阅读所有其他消息.

而且,最重要的是,该sse.php文件不知道它正在为哪个用户收集数据,因此它必须始终对所有用户进行操作.

如何创建一个sse.php文件,可以处理无限数量的唯一用户,并将数据发送给相应的用户?所以:

  1. 必须有一种方法可以将一些初始化数据(即唯一用户ID)发送到服务器端文件,以及

  2. 必须有一种方法只有那个特定的用户才能收到所收集的信息

Dar*_*ook 3

我是否只将数据发送给打开 sse.php 源的用户

是的。

或者每个登录、初始化连接的人都会收到相同的数据吗?

不。

如果每个用户都应该接收自己的私人提要,那么此方法将要求我为每个用户硬编码一个唯一的事件

幸运的是没有!SSE“事件”用于通过单个连接向单个用户发送不同类型的事件。一个用例可能是 Facebook 希望使用一个事件来发送聊天更新,另一个事件用于发送好友请求,另一个事件用于发送要显示的广告等。

在我的书中(使用 HTML5 SSE 的数据推送应用程序,http://shop.oreilly.com/product/0636920030928.do - 对插件表示歉意!)我认为它是多余的,最好包含在您的 json 对象中正在推动。

而且,最重要的是,sse.php 文件不知道哪个用户......

Cookie 已发送。因此,典型的方法是首先登录用户,创建一个对用户进行身份验证的 cookie,然后调用 sse 脚本。如果使用支持会话的服务器系统(例如 PHP),则 cookie 是一个实现细节。

无法发送 POST 数据和自定义标头。因此,如果 cookie 不是一个选项,您就必须使用 GET 来发布一些身份验证 ID(但正如您所注意到的,这不是最好的安全类型)。