武汉的开发者们注意啦!AI技术战略、框架以及最佳实战尽在Azure OpenAI Day 了解详情
写点什么

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:135958
用户头像

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

关注

评论

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

OmniReader Pro for Mac(图书阅读器) 2.6.2密码激活版

mac

苹果mac Windows软件 OmniReader Pro 阅读软件

SecureCRT for mac(终端SSH工具)v9.3.2激活版

影影绰绰一往直前

架构师的三类工作

agnostic

揭秘大脑中的贪婪因子:全面解析多巴胺

少油少糖八分饱

情绪 理性 大脑 快乐 多巴胺

JixiPix PuzziPix Pro for mac(强大的拼图软件)v1.0.20激活版

影影绰绰一往直前

Termius for Mac(SSH客户端)v8.4.0激活版

影影绰绰一往直前

FlowJo 10 for Mac(流式细胞分析软件)v10.4激活版

影影绰绰一往直前

What's new in Pika v3.5.2

apache/dubbo-go

redis 底层原理 Redis 7 Pika

云原生微服务的SWOT分析

俞凡

微服务 云原生

JetBrains PhpStorm 2023 for Mac(PHP集成开发)v2023.2.4中文激活版

影影绰绰一往直前

Medis for Mac(可视化管理工具)v2.13.0激活版

影影绰绰一往直前

架构实战营模块 2 作业

陈斌

架构实战营

再也不怕面试官问缓存雪崩、缓存击穿、缓存穿透了

程序员花卷

缓存 后端 缓存雪崩 布隆过滤器 可靠性设计

抖音商品详情接口在电商行业中的重要性及实时数据获取实现

Noah

选择适合您网站的 SQL 托管:MS SQL Server、Oracle、MySQL

小万哥

MySQL 数据库 程序员 sql 后端开发

Proxifier for mac(全局代理客户端)稳定版v3.11激活版

影影绰绰一往直前

04 | 复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度

鲁米

CorelDRAW Graphics Suite 2023 for Mac(矢量图形设计工具) 完美激活版

mac

苹果mac Windows软件 矢量图形设计软件 CorelDRAW 2023

高防服务器租用注意事项

Geek_f19a80

服务器

mybatis-plus代码生成器

智慧源点

Mybatis Plus 代码生成器

Go 程序编译过程(基于Go1.21)

-Hedon🍭

Go 编译原理 Go 面试题 面经 后端 大厂 Go编译过程

DevOps|研发提效-敏捷开发之每日站立会

laofo

DevOps Scrum 敏捷开发 研发效能 每日站会

JProfiler for Mac(Java开发分析软件)v14.0.0永久激活版

影影绰绰一往直前

抖音订单接口在电商行业中的重要性及实践应用

Noah

Studio One 6 Pro for mac(音乐创作编辑软件)v6.2.0永久激活版

影影绰绰一往直前

[大厂实践] Netflix容器平台内核panic可观察性实践

俞凡

Kubernetes netflix 大厂实践

糟了,数据库崩了,又好像没崩

越长大越悲伤

MySQL MySQL 8.0

文心一言 VS 讯飞星火 VS chatgpt (148)-- 算法导论12.2 3题

福大大架构师每日一题

福大大架构师每日一题

一款充电桩解决方案设计

攻城狮Wayne

大模型技术的发展与实践 主赛道:技术人的 2023 总结

攻城狮Wayne

大模型 ChatGPT LLM

在Go中构建复杂对象: 构建器模式指南

俞凡

golang 设计模式

WebSockets与Bayeux/CometD_Java_Alex Blewitt_InfoQ精选文章