我有一个应用程序,其中不同的用户监听服务器发送的事件源以获得定期响应。我打算从服务器发送响应,并以json格式发送相应的Id和数据。在客户端,当数据到达时,每个客户端都会检查匹配的Id,如果发现,则处理数据,否则忽略它。但这种方法的缺陷在于,每个用户都从定期更新中获得数据,即使这些数据不是为他们准备的。我读了一些关于sse的文章,但找不到任何关于这方面的信息
我的问题是使用服务器端事件是否有任何方法向特定侦听器发送响应,如果有,如何发送。?
我所做的是注册用户/要求用户登录并返回一个唯一的标识密钥。使用此键作为事件名事件监听器在注册/登录$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;
基于问题澄清的更新:如何阻止客户端接收不适合它的 SSE 消息。
最好的方法是不发送它。在服务器端过滤消息。(正如我答案的前面部分所解释的,这很容易,因为每个SSE连接都已经有一个专用的服务器进程来决定向它发送哪些数据。)这种方法在所有方面都优于(CPU/内存、网络带宽、安全性、隐私、程序员工作)。
另一种选择是在客户端过滤它,有两种方法可以做到这一点。一种是向客户端发送json数据。在您的onMessage()
处理程序中,使用其中一个字段来决定此消息是否适用于此客户端。
另一种方法是使用SSE的事件:
字段,然后监听该消息:
es = new EventSource(...);
es.addEventListener("forUser123", function(e) {
//Process their data here
}, false);
在发送< code>data:字段之前,将在服务器上设置< code>event:forUser123头。(但是,如果您必须麻烦地添加一个额外的头,最好在这一点上过滤您发送的消息。)
原始答案
你想做的事情(特定于客户端的)很容易,你认为服务器发送事件工作(广播)的方式更难。
与服务器的每个事件源
连接都是一个专用套接字。因此,它就像与Web服务器的任何其他连接一样,唯一的区别是套接字没有关闭,而是保持打开状态,因此服务器可以继续发送数据。这也意味着服务器上有一个专用的进程或线程来处理要发送到该客户端的消息。
因此,服务器知道每个用户是谁(假设他们用会话cookie来标识自己),并可以选择向客户端发送什么数据。
旁白:为什么播音比较难?假设您有100个连接的SSE客户端——实际上您有100个独立的服务器进程在运行。要向所有100个进程广播一条消息,首先必须告诉这100个服务器端进程该消息是什么,以便它们可以传递它。您可以使用上游套接字来实现这一点,或者它们可以定期轮询“messagesToSendToEveryone”数据库表,以查看是否添加了任何新内容。
是否可能有一个全局鼠标运动监听器,根据点击的JPanel的内容而具有不同的效果(仅使用一个鼠标运动监听器)? 例如:我有一个JFrame,其中添加了两个JPanel,并在JFrame中添加了一个鼠标运动监听器。当我点击一个JPanel时,我希望屏幕能够调整大小,但当我点击另一个JPanel时,我希望JFrame能够被拖动。我认为这可以通过使用JLabel来完成,使用JLabel的文本进行检查,与J
要运行Kafka,需要在文件。有两种设置我不理解。 有人可以解释侦听器和广告侦听器属性之间的区别吗? 留档说: 侦听器:套接字服务器侦听的地址。 和 advertised.listeners:主机名和端口代理将向生产者和消费者做广告。 我什么时候必须使用哪个设置?
概述 客户端代码 概述 建立连接 open事件 message事件 error事件 自定义事件 close方法 数据格式 概述 data:数据栏 id:数据标识符 event栏:自定义信息类型 retry:最大间隔时间 服务器代码 参考链接 概述 传统的网页都是浏览器向服务器“查询”数据,但是很多场合,最有效的方式是服务器向浏览器“发送”数据。比如,每当收到新的电子邮件,服务器就向浏览器发送一个“
概述 客户端代码 概述 建立连接 open事件 message事件 error事件 自定义事件 close方法 数据格式 概述 data:数据栏 id:数据标识符 event栏:自定义信息类型 retry:最大间隔时间 服务器代码 参考链接 概述 传统的网页都是浏览器向服务器“查询”数据,但是很多场合,最有效的方式是服务器向浏览器“发送”数据。比如,每当收到新的电子邮件,服务器就向浏览器发送一个“
我有一个监听两个不同端口的TCP服务器。我创建了两个不同的套接字,一个在端口8888上,一个在端口6634上。我监听这些端口,然后我在FD_SET中添加两个套接字,并将它们传递给Select()函数...当套接字准备好读取时,我检查FD_ISSET,看看哪个端口上有消息要读取。 不管怎样,当我连接到8888端口时,构思是成功的,我可以向服务器发送和接收。。。当我在客户端ctrl c时,选择函数再次
我有一个正在Eureka服务器上注册的服务“a”,我希望Eureka服务器在每次在Eureka内注册新服务时通知该服务。有什么办法吗?