多服务器实例环境下,服务器如何使用SSE发送消息

8
我有一个问题,如何在多个服务器环境中使SSE工作。
在用户界面(UI)中,有两个步骤:
1. source = new EventSource('http://localhost:3000/stream');
   source.addEventListener('open', function(e) {
      $("#state").text("Connected")
    }, false);
  1. 用户在UI界面上可以向API发布请求以更新数据

  2. 用户向API发布请求后,服务器会向UI发送事件以更新UI

在一个服务器环境中,这个功能完全正常,没有任何问题。

但在多服务器实例环境中,这将无法正常工作。例如,我有两个服务器实例,UI订阅了服务器1,然后服务器1记住了连接,但数据更新是来自服务器2的,当数据发生更改时,服务器2中没有SSE的连接。那么,在这种情况下,如何让服务器2向UI发送SSE呢?

为了使SSE在多服务器环境中正常工作,我们需要采用任何保存解决方案来保存连接信息,以便任何服务器实例都可以准确地向UI发送SSE吗?

让我更明确一下:是的,服务1和服务2都在负载均衡器后面,它们不必拥有相同的URL。UI是纯前端应用程序,甚至可以是移动应用程序。因此,如果UI向服务器1的LB发送eventSource请求,那么只有该实例才能使用此连接将事件发送回UI,对吗?但是,如果我们有多个服务器1实例,这意味着除当前实例之外的任何服务器1实例都无法将事件发送回UI。我认为这是SSE的限制,除非连接可以在所有实例之间共享。但如何做到这一点呢。

谢谢


服务器1和服务器2都在负载均衡器后面吗?也就是说,对于客户端浏览器来说,它们是相同的URL吗?还是它们具有不同的(全局)主机名和/或端口?顺便问一下,“UI”是指用户界面,即客户端浏览器吗? - Darren Cook
@DarrenCook,请看我上面的修改。不知道你是否遇到过同样的情况。 - user3006967
1个回答

8
如果您有两个具有不同URL的服务器,请从每个客户端向每个服务器建立一个SSE连接。
请注意CORS限制,即同源策略。 (它与xhr2 CORS的工作方式相同,因此很容易在谷歌上找到; 我的书还在第9章中详细介绍了它。)
如果您有两台位于负载均衡器后面的服务器,并且负载均衡器向客户端呈现单个URL,则只需确保负载均衡器正确配置。 即始终将该套接字传递到正确的服务器。 如果后端服务器死机并需要更换,则负载均衡器应关闭SSE套接字; 客户端将自动重新连接并获取新的后端服务器。
位于负载均衡器后面的多个服务器,应该要么具有自己的数据推送套接字连接到主数据源,要么应该全部轮询主数据源。

如何在同一服务器的两个实例之间重用连接(从UI到API)是一个挑战。不知道是否有任何好的参考资料可以遵循。 - user3006967
除非我误解了,否则使用SSE是不可能实现的(它只是一个TCP/IP套接字,会无限期地保持打开状态)。断开连接并连接到另一个服务器。或者打开两个SSE连接。 - Darren Cook
没错,这也是我对SSE的看法,谢谢。 - user3006967

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接