有没有办法让每个用户运行一个服务器发送事件而不是每个标签?

时间:2015-08-28 18:28:31

标签: javascript php websocket server-sent-events

我遇到了很多问题,因为我的用户使用多个浏览器标签来使用同一个应用程序。

问题是每个选项卡将与服务器建立单独的连接以启动服务器发送的事件,服务器将运行循环以完成请求。 (如果每个用户打开5个选项卡,那么服务器必须启动5个不同的server-sent-event来响应!)

有没有办法添加某种逻辑来检查客户端和服务器发送的脚本之间是否建立了连接,使用相同的连接而不是创建新连接?

我认为这与使用WebSocket的想法相同。但是,我使用WebSockets的问题是每个用户必须使用服务器发送的事件进行身份验证,并且不确定WebSockets是否可以这样做。当用户登录到应用程序时,我会生成一个sessionID,并且会话在允许他们使用该站点之前检查他们的IP /代理数据是否匹配。

如何将每个用户与Server-Sent Event的连接最小化为1?

3 个答案:

答案 0 :(得分:3)

在设置每个客户端的连接时,WebSocket服务器可以使用HTTP标头(以及cookie)。

但是,既然你没有使用WebSockets(还是?),那么下一个最好的选择就是你的客户端Javascript。

除非Cookie设置了HttpOnly标志,否则Cookie会在那里提供。这将是您在多个浏览器标签中匹配用户的最可靠方式。

浏览器用户代理字符串加上他们的IP地址很诱人,但请记住,大多数家用路由器都使用NAT,而且许多住在一起的人会倾向于在不同的计算机上使用相同的浏览器。

答案 1 :(得分:1)

  • 每个连接限一个用户?是。
  • 获取多个标签以共享相同的SSE连接?是的,理论上。

扩展第一点:您提到您正在使用PHP会话。会话cookie将从每个选项卡发送,因此当第一个选项卡连接时,您的PHP脚本可以在会话(*)内设置一些内容,表示您现在具有SSE连接。当第二个选项卡连接时,您的PHP脚本将查找该会话变量,查看它并返回错误代码。

关于第二点,这成为一个选项卡间通信问题:第一个选项卡需要有一种方法来检测第二个选项卡是否存在,并且必须有一种与之通信的方式,以便它可以转发它收到的SSE消息。我相信HTML5共享Web工作者可以做到这一点,我看到人们建议将它用于你描述的SSE用例,但我还没有看到一个有效的例子。

*:一旦PHP脚本开始提供SSE数据,请记得使用session_write_close关闭会话,以便其他脚本可以使用该会话。 (默认情况下,PHP会话在脚本的生命周期内被锁定。)

答案 2 :(得分:0)

如果用户已通过身份验证,那么您可能会有一些用户记录。将会话ID添加到该用户记录中,以便只响应该用户。

听起来您正试图阻止使用相同的身份验证详细信息进行并发使用。执行该操作的最佳方法是静默忽略并发请求。