Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何区分不同的服务器发送事件侦听器?_Javascript_Jquery_Server Sent Events - Fatal编程技术网

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

Javascript 如何区分不同的服务器发送事件侦听器?,javascript,jquery,server-sent-events,Javascript,Jquery,Server Sent Events,我有一个应用程序,其中不同的用户监听服务器发送的事件源以获得周期性响应。我打算从服务器发送带有相应Id和json格式数据的响应。在客户端,当数据到达时,每个客户端都会检查匹配的Id,如果发现它会处理数据,否则会忽略它。但这种方法的缺陷是用户从定期更新中获取数据,即使这不是为他们准备的。我读了一些关于sse的文章,但找不到任何关于这方面的内容 我的问题是使用服务器端事件是否有任何方法向特定侦听器发送响应,如果有,如何发送?根据问题说明更新:如何停止客户端接收不适用于它的SSE消息 最好的办法是不要

我有一个应用程序,其中不同的用户监听服务器发送的事件源以获得周期性响应。我打算从服务器发送带有相应Id和json格式数据的响应。在客户端,当数据到达时,每个客户端都会检查匹配的Id,如果发现它会处理数据,否则会忽略它。但这种方法的缺陷是用户从定期更新中获取数据,即使这不是为他们准备的。我读了一些关于sse的文章,但找不到任何关于这方面的内容


我的问题是使用服务器端事件是否有任何方法向特定侦听器发送响应,如果有,如何发送?根据问题说明更新:如何停止客户端接收不适用于它的SSE消息

最好的办法是不要把它寄出去。从服务器端筛选消息。(正如我回答的前面部分所解释的,这很容易,因为每个SSE连接都有一个专用的服务器进程来决定向它发送什么数据。)这种方法在所有方面都是优越的(CPU/内存、网络带宽、安全性、隐私性、程序员的努力)

另一种选择是在客户端对其进行过滤,有两种方法可以做到这一点。一种是向客户端发送json数据。在
onMessage()
处理程序中,使用其中一个字段来确定此消息是否用于此客户端

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

es = new EventSource(...);
es.addEventListener("forUser123", function(e) {
  //Process their data here
  }, false);
在发送
数据:
字段之前,将在服务器上设置
事件:forUser123
标题。(但是,如果您不得不费劲添加额外的头,那么最好在此时过滤您发送的消息。)


原始答案

您想要做的事情(特定于客户端)很简单,而您认为服务器发送事件(广播)的方式更难

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

因此,服务器知道每个用户是谁(假设他们通过会话cookie识别自己),并可以选择向该客户端发送什么数据


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

我所做的是注册用户/要求用户登录并返回唯一的标识密钥。使用此密钥作为事件名称事件侦听器在注册/login$post()的回发成功函数中初始化

因此,基本上每个事件侦听器都侦听一个唯一的事件。在服务器端,每个事件名称后面都会广播数据,所以唯一的事件侦听器只会获取针对它们的消息

客户端
是的,事实上你必须把它送到一个特定的地方;广播功能只需循环所有用户并向每个用户发送相同的消息。。。在发送之前在服务器上运行IF,而不是在它到达后在客户端上运行…@dandavis如何使用自定义事件名称将其发送到特定的服务器?我刚刚注意到标记。您是否在询问如何在客户端处理消息?(无论哪种方式,我都不认为需要jquery标记?)。那么,你能详细说明一下它是如何工作的吗?@baynezy我可以提供完整的框架结构和代码,但这将是很长的,实际上,没有登录的聊天应用程序用户会向服务器发送聊天。服务器定期检查数据库中的传入聊天,然后为聊天记录表和sse提要生成页面制定回复和插入表检查未查看的消息并广播消息每个客户端源分析消息以及Id是否匹配附加到聊天作为回复。我问您如何将数据发送到为您的effort@SachinDivakar听起来我会这么做,所以我不确定你剩下的问题是什么?一旦你为你的用户轮询了数据库中的消息,您只需将输出写入stdout。是的,客户端是服务器侦听器侦听事件源的地方,当收到数据时,它会检查其用户是否正确。所以我的问题是如何防止数据在客户端暴露给用户side@SachinDivakar我用更多的解释更新了我的答案。希望它能有所帮助。同样,我也是这么想的,事实上也是这样。我已经实现了自定义事件。首先,当用户注册聊天时,它会从服务器返回自定义标识Id作为响应。所以服务器会广播结果,并将其发送到相应的事件侦听器,但这种方法让我遇到了一个新问题,所以我问这个问题是为了弄清楚是否还有其他perpsective,为什么不在后端筛选器事件中使用查询字符串?我以这种方式实现了您可以看到一个最小的示例[这里](
$.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;