如果没有更多的上下文,这个问题很难回答,但我会尽力而为。
您可以将事件资源视为推送所有消息的管道,并让客户端侦听特定事件,从而有效地进行多路复用:
var handler = console.log.bind(console)
, events = new EventSource("/events")
events.addEventListener("new-friend", handler)
events.addEventListener("new-message", handler)
events.addEventListener("new-notification", handler)
这会将您的连接数减少到恰好一个,并且可以避免您在视图之间切换时进行代价高昂的重新连接。但是,它的缺点是您的服务器将(可能)不必要的数据推送到管道中。毕竟,您一次只能查看一种消息类型。您应该考虑这是否是一个实际问题。如果您的 UI 应该更新,可能带有某种标记通知(如 facebook 的消息或通知图标),那么您将需要了解这些消息,即使用户可能没有在该特定视图上活跃。无论如何,为了性能起见,您应该尽量保持消息精简。
如果您不能或不会将所有消息推送到同一个管道,您可能应该先考虑拥有多个资源或能够查询相关资源,然后打开和关闭连接。请记住,这可能会非常昂贵,因为客户端最终可能会用请求敲击服务器。每个视图更改都会导致连接的建立和拆除。它看起来像这样:
/* Assuming jquery is available and with the following html:
* <a class="stream" href="/friends>Friends</a>
* <a class="stream" href="/messages>Messages</a>
* <a class="stream" href="/notifications>Notifications</a>
*/
var currentEvents
, handler = console.log.bind(console)
$("a.stream").on("click", function() {
$el = $(this)
currentEvents && currentEvents.close()
currentEvents = new EventSource($el.attr("href"))
currentEvents.addEventListener("message", handler)
return false
})
最后,这取决于上下文。如果用户不经常切换视图,或者消息非常大,那么您可能希望采用第二种方法。它会在管道中提供更少的数据,但会在用户导航时创建和拆除连接。但是,如果用户经常切换视图,或者您可以保持消息大小合理,那么我会提倡多路复用,就像在第一个解决方案中一样。它将保持一个长时间运行的连接,可以将不同类型的小消息推送到客户端。