有没有一种方法可以使使用服务器发送的事件持久化

Is there a way to make Using server-sent events persistent?

本文关键字:服务器 持久化 事件 可以使 方法 一种 有没有      更新时间:2023-09-26

我需要运行一个每秒更新一次用户浏览器的脚本。我的需求是从服务器到客户端的单向通信。

为此,我实现了从服务器到用户客户端的服务器发送事件轮询。

问题是允许用户"通过打开多个浏览器选项卡"打开与服务器的多个连接,这是一个问题,因为它会增加服务器的开销。

我想将来自单个用户的连接限制为1。这意味着在所有选项卡上都可以连接到服务器。客户端和服务器之间的一个连接,即使用户打开了10个浏览器选项卡。

这是我的服务器发送的事件实现

var evtSource = new EventSource('getMyMessages.php');
evtSource.addEventListener("getMessagingQueue", function(e) {
    console.log(e);
    var data = JSON.parse(e.data);
    processServerData(data);
}, false);
evtSource.onerror = function(e) {
    evtSource.close();
};

有没有办法使这种沟通方式持久化?

在应用程序级别:使用PHP会话。

当你使用PHP会话时,PHP脚本会锁定它。这意味着没有其他脚本可以访问该会话。在你的情况下,这就是你想要的。(在最近的另一个问题中,服务器发送事件轮询导致长时间延迟,这就是问题的原因。)

如果你要求他们登录会话才能使用它,这会更好。(否则,禁用cookie的人仍然可以访问多个选项卡。)

问题是,他们的其他选项卡就在那里,而且(我相信)PHP进程在等待会话解锁时,正在耗尽服务器上的资源。

您可以通过使用会话变量来记录他们是否有当前连接,并确保释放会话锁定(如另一个问题中所述)来解决资源使用问题。然后,当用户尝试多次连接时,您可以向用户提供一条友好的错误消息。

在代理/防火墙级别:设置一个规则,不允许相同的东西一次连接到同一个URL(在这种情况下是SSE脚本)。重定向到一个错误页面,解释为什么不允许他们这样做。

东西的明显但糟糕的选择是它们的IP地址。这很糟糕,因为多个用户可能来自同一个IP地址。你可以使用他们的用户代理,但同样不可靠。给他们一块饼干,然后寻找它会更好。(您甚至可以查找PHP会话cookie。)