我遇到了很多问题,因为我的用户使用多个浏览器的选项卡来使用同一个应用程序。
问题是每个选项卡都将单独连接到服务器以启动服务器发送的事件,并且服务器将运行一个循环来满足请求。(如果每个用户打开5个选项卡,则服务器将必须启动5个不同的服务器发送的事件来响应!)
是否有办法添加某种逻辑来检查客户端和服务器之间是否建立了连接-发送的脚本使用相同的连接而不是创建新的连接?
我认为这和使用WebSocket的想法是一样的。但是,我使用WebSocket的问题是,每个用户都必须使用服务器发送的事件进行身份验证,并且不确定WebSocket是否可以做到这一点。当用户登录到应用程序时,我生成一个sessionID,会话会检查他们的IP/代理数据是否匹配,然后才允许他们使用网站。
如何将到服务器发送事件的连接最小化为每个用户1个?
4条答案
按热度按时间fiei3ece1#
在设置每个客户端的连接时,WebSocket服务器可以使用HTTP头(以及Cookie)。
但是,由于您还没有使用WebSockets(还没有?),因此下一个最好的选择是您的客户机Javascript。
除非cookie设置了HttpOnly标志,否则在那里可以使用cookie。这将是在多个浏览器选项卡中匹配用户的最可靠方法。
浏览器用户代理字符串加上他们的IP地址是诱人的,但请记住,大多数家庭路由器使用NAT,许多住在一起的人往往会在不同的计算机上使用同一个浏览器。
0vvn1miw2#
关于第一点:您提到您正在使用PHP会话。会话cookie将从您的每个选项卡发送,因此当第一个选项卡连接时,您的PHP脚本可以在会话(*)中设置一些内容,表示您现在有SSE连接。当第二个选项卡连接时,您的PHP脚本将查找该会话变量,看到它,并返回一个错误代码。
关于第二点,这变成了选项卡间的通信问题:第一个选项卡需要有一种方法来检测第二个选项卡的存在,并且必须有一种方法来与它通信,以便它可以转发它接收到的SSE消息。我相信HTML5共享Web工作者可以实现这一点,我看到有人建议将它用于您描述的SSE用例,但我还没有看到一个工作示例。
session_write_close
关闭会话,以便其他脚本可以使用该会话。(默认情况下,PHP会话在脚本的生命周期内是锁定的。)vmdwslir3#
如果用户已通过身份验证,则您可能有一些用户记录。请向该用户记录添加会话ID,以便只响应该用户记录。
这听起来像是你试图阻止同时使用相同的身份验证细节。最好的方法是默默地忽略并发请求。
kyks70gy4#
这是一个很好的问题,也是很多年后的回答,但是您的用例似乎有点奇怪
根据您下面的引述。我的用户使用多个选项卡来使用同一个应用程序。首先,他们是否希望在每个选项卡上看到相同的数据?我不明白为什么有必要这样做?如果其他选项卡打开,您是否希望担心焦点所在的选项卡?
现在,如果他们打开了多个选项卡来使用不同的信息,例如一个金融应用程序,其中1.是美国股票市场2.是英国股票市场3.是亚洲股票市场。这我可以理解。但这也会使您无法使用模糊处理。也就是说,如果用户点击离开选项卡并将其报告给服务器以关闭(),我宁愿关闭连接。
如果你不这样做,那么你应该控制你的超时时间,因为这会导致大量的内存泄漏。所以,要小心。用户会做任何你让他们做的事情。
你可以使用的一种机制是一个活动的
blur
会话。这意味着,如果用户点击了标签blur,你可以为预期的使用时间设置一个超时。如果屏幕是活动的,你可以刷新连接并重新启动计时器。所以,对我来说,从一个经过身份验证的用户那里获得一个标签页并打开多个标签页是很容易的。事实上,这是默认的。但这也是问题所在。
当你说:
是否有办法添加某种逻辑来检查客户端和服务器之间是否建立了连接-发送的脚本使用相同的连接而不是创建新的连接?
如果把数据放到多个标签上是一个大问题,我会怎么做?对我来说,我喜欢“嘿,你得到一个标签,先生/女士”,这就是它的方法。
我将探索一种
blur
方法,该方法将从开放流中获取数据,并将其添加到redux或ngrx抽象或数据流抽象中的浏览器会话中(两者都具有设置的复杂性)。这样做的意思是,“如果用户点击关闭选项卡”(非活动选项卡),则默认使用来自传入事件流的备份数据流。因此,关闭主数据流,并使用从该流传入的生成的数据数组。运行内存中的/redux/ngrx或一个单独的服务器,如
Redis
或Mongo
。Auth 0在一篇文章中有一个很好的例子。
Handling Connection Recovery on Server-Sent Events
在这个例子中, Postman 解释说,可以通过跟踪发送的消息来处理丢失的连接和恢复,并且如果连接丢失,则会向服务器发送信号。
Last-Event-Id
这将告诉用户发送的最后一条正确消息,并将混乱的消息和新消息按顺序传递给用户。现在,这个例子并不是你需要做的,但重点是一样的。保存消息并以不同的方式传递它们,这样当用户点击其他标签时,你就可以关闭它们。这样,你将在活动标签上有1个sse连接,而其他标签只会从其他机制运行一个副本。保持连接质量,而且只有一个。
希望这能帮助到一些人。
我遇到了很多问题,因为我的用户使用多个浏览器的选项卡来使用同一个应用程序。
问题是每个选项卡都将单独连接到服务器以启动服务器发送的事件,并且服务器将运行一个循环来满足请求。(如果每个用户打开5个选项卡,则服务器将必须启动5个不同的服务器发送的事件来响应!)
是否有办法添加某种逻辑来检查客户端和服务器之间是否建立了连接-发送的脚本使用相同的连接而不是创建新的连接?