如何区分不同服务器发送的事件监听器?

how to differentiate between different server sent event listeners?

我有一个应用程序,其中不同的用户侦听服务器发送的事件源以获取定期响应。我打算从服务器发送具有相应 ID 和数据的响应 json format.And 在客户端每个客户端在数据到达时检查匹配的 Id,如果发现它处理数据,否则忽略 it.But 这种方法的缺陷是每个用户从定期更新中获取数据,即使它不是为了 them.I 阅读一些关于 sse 的文章,但找不到关于此的任何信息

我的问题是使用服务器端事件是否有任何方法可以向特定的侦听器发送响应,如果是的话如何.?

UPDATE 基于问题的澄清:如何阻止客户端接收不适合它的 SSE 消息。

最好的办法就是不发。过滤消息 server-side。 (正如我回答的前面部分所解释的,这很容易,因为每个 SSE 连接已经有一个 专用 服务器进程来决定向它发送什么数据。) 这种方法在所有方面都优越(CPU/memory、网络带宽、安全性、隐私、程序员的努力)。

另一种方法是过滤它 client-side,有两种方法可以做到这一点。一种是向客户端发送 json 数据。在您的 onMessage() 处理程序中,使用这些字段之一来确定此消息是否针对此客户端。

另一种方法是使用 SSE 的 event: 字段,然后收听该消息:

es = new EventSource(...);
es.addEventListener("forUser123", function(e) {
  //Process their data here
  }, false);

event:forUser123 header 将在您发送 data: 字段之前在服务器上设置。 (但是,如果您不得不费心添加额外的 header,此时最好过滤您发送的消息。)


原答案

你想做的事情(成为client-specific)很容易,而你认为​​Server-Sent-Events的工作方式(广播)更难。

与服务器的每个 EventSource 连接都是专用套接字。所以它就像任何其他连接到 Web 服务器一样,唯一的区别是套接字没有关闭,而是保持打开状态,以便服务器可以继续发送数据。这也意味着服务器上有一个专门的进程或线程来处理发送给该客户端的消息。

因此,服务器知道每个用户是谁(假设他们使用 session cookie 来标识自己),并且可以选择向该客户端发送哪些数据。

旁白:为什么广播更难? 假设您有 100 个连接的 SSE 客户端 - 您实际上有 100 个独立的服务器进程 运行。要向所有 100 个进程广播一条消息,您首先必须告诉这 100 个 server-side 进程消息是什么,以便它们可以传递它。您可以使用上游套接字执行此操作,或者他们可能会定期轮询 "messagesToSendToEveryone" 数据库 table 以查看是否添加了任何新内容。

我所做的是注册用户/要求用户登录和return一个唯一的标识key.Using这个键作为事件名称事件监听器在post后面被初始化registration/login $post();.

的成功函数

所以基本上每个事件侦听器都会侦听一个唯一的事件。在服务器端广播每个事件名称后跟数据,因此唯一的事件侦听器会收到仅供他们使用的消息。

客户端

$.post( "chatReg.php", { xxx: xxxx, time: xxx}).done(function( data ) {

     if((typeof(EventSource) !== "undefined")&&((localStorage.getItem("uname") !== null))) {
    var source = new EventSource("XXXXXXXX.php");   

    source.addEventListener(localStorage.getItem("uname"), function(e) {
     var data = JSON.parse(e.data);

     $('div.chat-box-content').append('<div class="msgWrapper"><div class="msgwrapperleft"><div class="iconright"><img src="http://placehold.it/40X40"></img></div><div class="MessageRight">'+data.Message+ '</div> </div><p class="ArrivedTimeRight"><span ><span class="timeago" >'+CreateTimestamp()+'</span></span></p></div>');

    }, false);


    } 

}

服务器

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

    echo  'event: '.$row['SpecialId'];
            echo PHP_EOL;

            echo  'data: {"Message":"'.$row['Message'].'","xxxId":"'.$row['xxxId'].'"}';
            echo PHP_EOL;
            echo PHP_EOL;