智能体刷屏的背后,是 AI 应用拐点的来临?AICon 北京站议程重磅公布,50+ 硬核分享不容错过 了解详情
写点什么

WebSockets 与 Bayeux/CometD

  • 2010-05-30
  • 本文字数:2762 字

    阅读完需:约 9 分钟

此时有两种技术可以将通信引入基于浏览器的应用之中:Bayeux(又称 CometD)和 WebSockets。究竟接下来会是一方被另一方所取代,还是双方藉由显著的差异化实现共同发展呢?

CometD 框架是 Bayeux 协议的实现,可以使得服务器端和客户端在不可靠的网络上进行多通道异步通信。该实现用到了多种语言( JavaScript Java Perl 等等),但是主要还是基于浏览器的 AJAX 应用。Bayeux 的优势在于,它可以运行在任何支持 AJAX 的浏览器上,在现有 HTTP 通信机制下,就能够让浏览器支持异步后台的更新,比如类似于 Google 邮件的新邮件通知的新信息送达。事实上,同样的协议还可以用于使用其他语言在不可靠的网络上连接设备进行通信(比如移动设备)。

WebSockets 是一个标准草案,这项草案由Google、Apple 和其他进行 HTML 5 标准化的 WhatWG 工作组成员所资助。因此,支持 HTML 5 的浏览器(Chrome 或者 Safari)已经开始支持内建的 WebSocket 协议。

这两个协议的目标都是让基于 Web 的 AJAX 应用能通过异步消息或者基于 Socket 的连接进行通信,而不是在一个现有应用之上再搭建一个自己实现的通信层。这使得在设计应用的时候,可以只关注于组件部分,而把消息传递给通信层去递送。另外,这两个协议都能够建立长连接,事件可以通过长连接异步地递送给应用。这没什么新鲜的:HTTP 1.1 就支持连接管道(可以在每个请求之后保持连接,并可以在第一个请求得到处理之后再发送多个请求);而像 IMAP 等一些协议则支持 IDLE 命令,把连接置成休眠状态,这样在休眠的连接上就不再有数据传输,但是服务器依然可以随时推送新消息。其实在 Bayeux 或者 WebSockets 之前,通过 HTTP 进行持久通信的机制一般被称为“ HTTP 推送”。

然而,长连接并不是没有任何问题。一条连接如果长时间没有数据通信的话,会被认为已经死掉,并在接下来的某个时间点被终止。为了解决这个问题,IMAP 的 IDLE 建议客户端每 29 分钟发送一个 IDLE 命令来避免断连。而 HTTP 代理则会决定连接是处于闲置状态并丢弃连接,而不去管客户端和服务器端是否已经保持了一条长连接。

资源限制也是一个问题。通常,浏览器都会限制对单个服务器的并发 HTTP 连接的数量,以避免对该服务器(或者网络连接)造成过大的压力。浏览器一般会将这个并发连接数量限制在每次 2 到 4 个。

Bayeux 和 WebSockets 都试图避免资源限制问题,使用回退机制来实现长轮询(比如 Bayeux),或者切换到其他非 HTTP 协议之上。那么,这些程序库的使用者就不需要再担心浏览器或者基础架构的限制问题。

Erlang 之父 Joe Armstrong 认为, WebSockets 将会干掉 Comet

在经过了一些试验以后,我可以让 Erlang 和一张 Web 网页通过纯异步消息传输进行通信。

我认为这意味着如下的技术将会消亡:

  • comet
  • 长轮询
  • AJAX
  • 连接保持 socket

其实核心的问题便是,Web 浏览器不能像其他应用一样,打开一个 socket 并进行异步 I/O。而上述技术只不过是些带有各种问题的权宜之计而已。

Jetty Bayeux 协议的创作者之一 Greg Wilkins 认为, WebSocket 规范还不够好,无论是规范的定义,还是连接中断时的行为,都需要改进和完善。其中一个关键问题,便出在协议的表述上:

然而这类规范的一个更实际问题便是规范写的很让人费解,比如:

使得 /b_v/ 为整数,并且为 /b/ 的低 7 位(这个值应由 /b/ 和 0x7F 进行 _and_ 位运算求得)。

将 /length/ 乘以 128,再加上 /b_v/,并将结果储存在 /length/ 中。

如果 /b/ 的高序位被置(例如,/b/ 和 0x80 进行 _and_ 位运算得到 0x80),那么返回到标记为 _length_ 的前一步骤。

我质疑到读者能否确认客户端的数据帧和服务器端的数据帧是对称的,并且由相同的数据帧实现。

相比较这些诘屈聱牙的论述,IETF 规范通常使用精确的扩展巴科斯范式(ABNF,RFC5234)来描述协议,这样便不会引起误读或者混乱。为了能更清楚的说明,我将 4.2 节翻译成了 BNF …

值得注意的是, Jetty 现在既支持 WebSocket 又支持 Bayeux。本着调查研究的精神,Greg 写了一篇博客,通过 WebSocket 实现了聊天功能。然而开发过程却并不顺利:

聊天室的典型用例是这样的,你进入了一个聊天室,标识出你的存在,这个标识会一直保持到你显式地退出聊天室。而在 Web 聊天的情况下,你可以收发聊天消息,直到你关闭浏览器或者转至其他网页。不幸的是,即便是这么简单的用例都无法通过 WebSocket 实现,因为在该协议中,连接有一个闲置超时。

为了保持存在的状态,聊天应用要发送“连接保持(Keep Alive)”的消息给 WebSocket,来避免该连接因为闲置超时而关闭。然而,应用并不知道这个闲置超时究竟是多少,因此它只能随便选一个间隔周期(比如 30 秒)来发送该消息,这和长轮询要做的事似乎就多少有些类似了。

通过 onClose 处理、连接保持、消息队列、超时和重试,我们最终实现了一个可以在用户停留在网页上的时候保持其存在状态的聊天室。但是遗憾的是这个聊天室依然还没有完,因为它还需要处理错误和非暂时性故障。

Greg 对 WebSocket 协议的改进给出了一系列的建议,这些建议力图在将来给开发者们带来更多的便捷:

  • WebSocket 将来的版本最好能支持超时发现机制,这样它就可以告诉应用连接保持消息的周期,甚至它能够发连接保持的消息给应用。
  • WebSocket 将来的版本最好能支持有序关闭消息,这样应用就可以分辨出关闭的原因是网络错误(需要将用户的存在状态保持一段时间)还是一次有序关闭,就比如说用户离开了该页面(将用户的存在状态移除)。
  • WebSocket 将来的版本最好能支持顺序关闭,这样没有出错的连接上的递送便可以识别出来,除非服务质量的要求非常高,否则便可以避免复杂的确认。
  • WebSocket 将来的版本最好能支持更详细的连接错误,处理“找不到主机名”和处理“401 未授权”的方式肯定是不一样的。
  • WebSocket 将来的版本最好能支持发送错误状态,比如网络错误或者是闲置超时,这样应用就可以不必对错误进行重试。

最后,他概要性地总结了自己的观点,并谈了谈对未来的期望:

这篇博客说明了 WebSocket 不能解决很多在开发健壮 Comet 网络应用时遇到的复杂问题,也就是说没有银弹。希望在未来版本的 WebSocket 中,可以加入连接保持、超时处理、顺序关闭和错误通知等特性。但是 WebSocket 却不能提供高级的队列处理、超时、重连、重试和退避(Backoff)。如果你想拥有高品质的服务,那么无论是你的应用还是你的框架,都需要支持这些特性才行。

CometD 版本 2 即将发布,支持将 WebSocket 作为替代传输层,来支持现有的 JSON 长轮询和 JSONP 回调轮询。CometD 支持这篇博客所谈到的所有特性,并让它们对浏览器完全透明,无论是否支持 WebSocket 都可以做到。我们真心希望 WebSocket 可以给我们更大的吞吐量和更低的延迟,比现在已经让人印象深刻的长轮询要更好。

Jetty 8.0.0 M0 已经发布,提供了对 WebSocket 的支持,同时还支持 Servlet 3.0 API。

查看英文原文: WebSockets and Bayeux/CometD

2010-05-30 13:136303
用户头像

发布了 80 篇内容, 共 21.7 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

2021年大厂Java高级面试题分享,程序员Java基础入门

Java 面试 后端

2021年最新Java大厂面试笔试题分享,Java入门教程免费视频

Java 面试 后端

2021年最新Java面试经历,别再说自己不会了

Java 面试 后端

2021年网易Java岗面试必问,Java开发面试准备

Java 面试 后端

2021年腾讯Java高级面试题及答案,百度笔试题百度校招面试经验

Java 面试 后端

2021年互联网大厂Java笔经,Java自学宝典电子书下载

Java 面试 后端

2021年哔哩哔哩Java高级面试题及答案,大牛手把手教你

Java 面试 后端

阿里巴巴首发:Java核心框架指导手册,1小时点击量破千万!

Java 程序员 架构 面试 计算机

说下你可能没用过的EventBus

艾小仙

2021年京东Java岗面试必问,我在华为做Java外包的真实经历

Java 面试 后端

2021年这些高频面试知识点最后再发一次,面试官突击一问

Java 面试 后端

2021年抓住金三银四涨薪好时机,借花献佛

Java 面试 后端

“工业互联 在云之洲”丨“5G+AR”远程协助作业解决方案 赋能装备更智能

云计算,

2021年互联网大厂Java笔经,Java重点知识大全

Java 面试 后端

好看视频Android重构——围绕于播放器的重构实践

百度Geek说

性能优化 大前端 好看视频 播放器

2021年你与字节跳动只差这份笔记,大神码了2000页Spring全家桶笔记

Java 面试 后端

2021年华为Java面试真题解析,大厂面试必问

Java 面试 后端

一个简单的产品分析模型

石云升

产品经理 产品思维 9月日更 产品分析

2021年最新腾讯Java面经,Java面试高级题目

Java 面试 后端

Android音频架构| 社区征文

轻口味

android 音视频 新春征文

设计 | ClickHouse 分布式表实现数据同步

RadonDB

数据库 Clickhouse

2021年字节跳动、阿里等大厂最全Java面试题,1个月学会Java开发

Java 面试 后端

2021年抓住金三银四涨薪好时机,腾讯Java社招面试流程

Java 面试 后端

QOE 驱动下的分布式实时网络构建:Agora SD-RTN 的演进

声网

Java 人工智能 分布式 网络

2021年冲刺年薪40w,Java从基础到高级知识点汇总

Java 面试 后端

2021年哔哩哔哩Java高级面试题及答案,Java实战视频下载

Java 面试 后端

2021年春招Java面试题,大厂Java核心面试题出炉

Java 面试 后端

2021年是意义非凡的一年,2021阿里+头条+腾讯等大厂Java笔试题分享

Java 面试 后端

2021年最新Java面试点梳理,阿里P7大牛整理

Java 面试 后端

2021年互联网大厂Java笔经,Java程序员如何有效提升学习效率

Java 面试 后端

如何画UML,几种简单的模型分析

编程 架构 面试 后端

WebSockets与Bayeux/CometD_Java_Alex Blewitt_InfoQ精选文章