14

当使用服务器发送事件时,客户端应该建立多个连接来接收它感兴趣的不同事件,还是应该只有一个连接并且客户端通过单独的通道指示它感兴趣的内容?IMO 后者似乎更可取,尽管对某些人来说它可能会使客户端代码更复杂。该规范支持命名事件(与特定主题相关的事件),这对我来说建议服务器发送事件连接应该用作所有事件的单一通道。

以下代码说明了启动多个 Server-Sent Event 连接的第一种情况:

var EventSource eventSource1 = new EventSource("events/topic1");
eventSource1.addEventListener('topic1', topic1Listener, false);

var EventSource eventSource2 = new EventSource("events/topic2");
eventSource2.addEventListener('topic2', topic2Listener, false);

eventSource1 将接收“topic1”事件,而 eventSource2 将接收“topic2”事件。虽然这非常简单,但对于您感兴趣的每个主题都会发生挂起的 GET 也非常低效。

替代方法如下:

var EventSource eventSource3 = new EventSource("/events?id=1234")
eventSource3.addEventListener('topic3', topic3Listener, false);
eventSource3.addEventListener('topic4', topic4Listener, false);

var subscription = new XMLHttpRequest();
subscription.open("PUT", "/events/topic3?id=1234", true);
subscription.send();

在此示例中,将存在单个 EventSource,并且对特定事件的兴趣将由具有 Server-Sent Event 连接的单独请求指定,并且注册由 id 参数关联。topic3Listener 会收到“topic3”事件,而 topic4Listener 不会。虽然需要更多的代码,但好处是只建立了一个连接,但仍然可以以不同的方式识别和处理事件。

网络上有许多示例显示了命名事件的使用,但似乎事件名称(或主题)是预先知道的,因此客户端无需向服务器注册兴趣(示例)。虽然我还没有看到显示多个 EventSource 对象的示例,但我也没有看到显示客户端使用单独的请求来注册对特定主题的兴趣的示例,就像我在上面所做的那样。我对规范的解释使我相信,表明对某个主题(或事件名称)的兴趣完全取决于开发人员,并且可以在客户知道它将要接收的事件名称的情况下静态完成或客户端动态地提醒服务器它有兴趣接收特定事件。

我很想听听其他人对这个话题的看法。注意:我通常是 Java 开发人员,所以请原谅我平庸的 JS 代码.. :)

4

2 回答 2

5

恕我直言,我强烈建议您EventSource为每个提供 SSE 的服务拥有一个对象,然后使用不同类型发出消息。

但最终,这取决于消息类型的相似程度。例如,如果您有 5 种不同类型的与用户相关的消息,请拥有一个用户EventSource并区分事件类型。

如果您有一种关于用户的事件类型,而另一种关于三明治的事件类型,我会说将它们放在不同的服务中,因此EventSources。

将 EventSources 分解为与宁静服务相同的方式是一个好主意。如果您不会使用 AJAX 从同一个服务中获得两个东西,那么您可能不应该从同一个 EventSource 中获得它们。

于 2012-10-08T20:28:54.313 回答
1

为了应对模糊和宽松的浏览器标准解释*,浏览器供应商对允许到单个域/端口的持久连接数实施不一致的限制。由于异步上下文的每个事件接收器都假定只要该接收器处于打开状态,就会分配一个持久连接,因此严格限制 EventSource 侦听器的数量以避免超出不同的供应商特定限制是至关重要的。实际上,这将您限制为每个应用程序大约 6 个 EventSource/async 上下文对。降级是正常的(例如,额外的 EventSource 连接请求只会等到插槽可用),但请记住,必须有可用于检索页面资源、响应 XHR 等的连接。

*W3C 已经发布了关于持久连接的标准,其中包含“……应该限制同时连接的数量……”这种语言意味着该标准不是强制性的,因此供应商的合规性是可变的。 http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.4

于 2015-01-29T23:08:45.723 回答