使用 EventSource 和服务器发送事件构建的墙

EventSource 已在 Aurora 6 中实现。它是一种新的简化方式,用于打开与服务器的长期连接,并允许浏览器在服务器将消息流式传输到客户端时创建事件。它也可在 Chrome 和 Opera 中使用,并且还有其他浏览器的备用解决方案。

为社交应用创建墙/提要…

…只需几行代码(完整项目 可在 Github 上获取)。

消息

服务器将发送两种类型的消息
 ● 简单消息,以“data:”为前缀,从新行开始
 ● 带有特定事件名称的消息,类似于简单消息,但在前一行带有“event: <anEventName>”

在本例中,简单消息被视为用户的状态,特定事件将以特定颜色插入时间线中,尽管它们可能出现在页面上的不同位置。消息数据将以 JSON 格式发送,尽管它可以是纯文本字符串。

服务器

服务器将是一个虚拟的 .php 脚本,它从文本文件读取示例状态,并使用适当的标题逐个流式传输到客户端。

客户端

客户端将创建一个事件源,并为每个特定事件名称注册事件处理程序,以及为简单消息注册onmessage处理程序。

代码的剩余部分 可在 Github 上获取

备用方案

以下是其他浏览器可用的 polyfill/备用方案的简短列表
 ● Remy Sharp 的 polyfill
 ● Yaffle 的 polyfill
 ● Rick Waldron 的 jquery 插件

您是否有基于 EventSource 的 Web 应用示例要分享?

关于 louisremi

开发者关系团队、长期 jQuery 贡献者和开放 Web 爱好者。 @louis_remi

更多由 louisremi 撰写的文章…


23条评论

  1. louisremi

    需要注意的是,EventSource 规范目前阻止服务器脚本托管在不同的域上。

    我们交付的第一个实现符合规范,但我们认为这种可能性可以使开发者受益,因为将持久连接服务于自己的域是一种最佳实践。

    我们将尝试使 EventSource 跨域兼容,您可以在这里跟踪我们的进度: https://bugzilla.mozilla.org/show_bug.cgi?id=664179

    2011年6月16日 凌晨 07:44

  2. David illsley

    我一直缺少的拼图部分是处理失败… 连接断开等。我是否需要担心这个问题,或者重新连接会自动发生?

    2011年6月16日 凌晨 11:09

    1. louisremi

      有趣的问题:我们还没有关于这方面的任何文档,但阅读规范应该可以帮助您: http://www.w3.org/TR/eventsource/#eventsource
      我注意到(至少在 Firefox 中)如果用户在我的演示中按下 Esc 键,连接将关闭。

      2011年6月16日 凌晨 11:18

  3. David Illsley

    :( 我几周前查看了规范,它离可互操作性相差甚远。一直希望 Mozilla 能设定标准… 过于脆弱/不友好的移动网络和笔记本电脑盖子关闭,假定连接很健壮。

    2011年6月16日 凌晨 11:37

  4. sonny

    好文章,尽管我不会使用“墙”示例,因为它通常是那种可以从双向 WebSocket 支持中获益的应用。
    相反,我会使用一个例子,例如广播网站能够将当前歌曲的名称推送到听众。

    2011年6月18日 凌晨 10:39

    1. louisremi

      嘿 Sonny,
      让我不同意,在这些类型的墙上,您通常接收的数据比发送的数据多得多,而且您发送回的数据不需要实时处理。
      使用 EventSource,您可以使用标准 Web 服务器将数据流式传输到客户端(WebSockets 需要在服务器端进行特殊设置),并使用 XHR 不时地将数据发送到服务器。

      2011年6月20日 凌晨 08:13

  5. alain

    我喜欢这个演示,运行良好!
    今天我读到这篇文章,它介绍了 API 的演变

    http://blog.whatwg.org/weekly-back

    我认为这个墙示例应该更“完整”,采用多客户端版本,louisremi,您能确认我们需要某种服务器数据库访问才能实现这样的应用吗?由于 php 文件不知道不同的客户端,我认为我们需要类似的东西(可能是服务器上的平面文件)。

    2011年6月21日 凌晨 05:53

    1. louisremi

      是的,您需要在服务器上使用类似消息队列的东西来处理多个客户端

      2011年6月21日 凌晨 06:18

  6. alain

    谢谢 :)

    2011年6月21日 凌晨 06:26

  7. Vitaliy Kupets

    我很乐意看到 WebSockets 终于准备好了

    2011年7月11日 凌晨 05:54

  8. davide

    您好,感谢您发布有关此有趣功能的文章。
    上述方法,即服务器(例如 sse.php)运行无限循环并在每隔 N 秒唤醒一次以检查是否有要发送的事件/消息,是否始终是唯一的可用方法?
    这个问题来自以下 MVC 应用中使用事件的想法:当用户访问网站的某个特定页面(例如 fun.php)时,需要发送事件。是否有可能直接从 fun.php 发送消息,而不是将用于构建消息的数据传递到 sse.php(通过队列等)?

    2011年7月16日 凌晨 04:52

    1. louisremi

      您当然可以从生成正在访问的页面的脚本中发送事件。
      出于性能原因,您可能希望将持久连接托管在另一个服务器上,该服务器托管更合适的技术,例如 node.js 等。

      2011年7月20日 凌晨 06:40

  9. Jerome Louvel

    很高兴看到“服务器发送事件”在 Firefox 中取得进展。与 WebSockets 相比,它的优势在于它没有发明另一个协议,而是完美地契合了 HTTP 和 REST 架构风格。

    它可能无法覆盖所有实时用例,但它以非常标准、简单且强大的方式执行其功能。在 Restlet Framework 中,我们计划添加对它的支持,包括服务器端和客户端。

    2011年7月21日 凌晨 12:09

  10. Louis-Pierre Beaumont

    您好,

    感谢您提供这个很棒的演示。但是,我无法在我的机器上使用 EventSource。我总是收到错误提示,说 Firefox 无法与服务器建立连接。

    我做了一个小程序,它监听连接,然后进入一个简单的循环
    每隔 2 秒发送一次事件。当我将浏览器指向它的 URL 时,可以看到更新。但是,当我使用 new EventSource(urlOfProgram) 时,什么也没有发生。

    我是否需要将页面和程序都托管在相同的地址和端口上?

    2011年8月9日 凌晨 02:06

    1. louisremi

      是的,过去对服务器发送事件存在这样的限制。
      您很快将能够使用 CORS 标头将事件源托管在另一个域上

      2011年8月13日 凌晨 00:21

  11. Louis-Pierre Beaumont

    关于我上一次的评论

    我现在将页面和程序都托管在相同的地址和端口上,一切正常。

    2011年8月9日 下午 17:16

  12. Aaron

    在 Apache+PHP 上,这是否会导致允许的并发连接数达到上限?

    2011年8月16日 凌晨 09:12

    1. louisremi

      抱歉 Aaron,我不是 Apache 和 PHP 专家,无法回答这个问题。

      2011年8月17日 凌晨 02:11

      1. Davide

        我也有同样的担忧,而且还没有找到明确的答案,所以至少现在我还没有使用 SSE。

        2011年8月17日 凌晨 02:23

  13. Srirang (brahmana)

    您好,

    这些持久连接是否计入到对主机限制的最大并发连接数中?据我所知,目前对一个主机的限制是 6 个并发连接。

    我猜想这些连接确实是计入的,这也是作者建议将这些连接放在单独域名上的原因之一。

    2011 年 9 月 7 日 下午 3:28

    1. Sergiu

      我在应用程序中添加第六个 EventSource 时遇到了问题,服务器停止响应。我可以自定义允许的并发连接数量吗?还是这是一个预定义的规则?

      2013 年 3 月 20 日 下午 3:04

  14. Victor

    这个 EventSource polyfill 支持 CORS(IE8、Firefox、Chrome、Safari)

    https://github.com/Yaffle/EventSource

    2011 年 9 月 28 日 下午 4:46

  15. Gary Tessman

    我使用的是 OSX Lion 10.8.2、Firefox 16.0.2、Tomcat 7、Spring MVC 应用程序以及 DWR。使用一个简单的时钟,每 1000 毫秒发送一次,服务器发送事件在 Firefox 中似乎在一段时间后停止工作。我编写了一个 WebServlet 应用程序和一个 Spring MVC 控制器应用程序,Firefox 似乎在不到 20 分钟的时间内就停止接收/响应服务器发送事件。Chrome 没有这个问题,可以持续整晚。我怀疑这是 Firefox 中的一个错误,因为 Chrome 能够持续运行...而 Firefox 停止了。我很想知道大家可能有哪些建议,如果需要的话,我愿意提供任何代码作为演示。有没有人尝试过在 Firefox 中长时间使用 SSE?

    谢谢,
    Gary Tessman

    2012 年 10 月 27 日 下午 5:02

本文的评论已关闭。