CometD 长轮询协议及在Salesforce中的应用
CometD 协议是一种基于 HTTP 的实时通信协议,核心目标是解决传统 HTTP 短连接无法高效实现“服务器主动向客户端推送数据”的问题,其核心技术之一就是 长轮询(Long Polling)。在 Salesforce 等企业级系统中,CometD 常被用于实时接收平台事件(如 Platform Event
)、实时数据更新等场景。以下是其原理、长轮询机制细节及在 Salesforce 中的应用:
一、CometD 协议的核心定位
CometD 并非独立发明的全新协议,而是基于 HTTP/HTTPS 扩展的“准实时”通信标准,旨在实现 服务器到客户端(Server-to-Client)的双向实时数据传输。它的名字源于“Comet”(彗星)——象征数据像彗星一样“持续不断地从服务器流向客户端”,而“D”代表“Duplex”(双向),强调客户端与服务器的双向交互能力。
其核心价值:解决传统 HTTP “请求-响应”模式的局限性(客户端需频繁轮询才能获取新数据,导致延迟高、资源浪费),通过长轮询等机制实现“接近实时”的推送,同时兼容所有支持 HTTP 的网络环境(无需额外端口、不依赖 WebSocket 等特殊协议)。
二、核心机制:长轮询(Long Polling)如何工作?
长轮询是 CometD 实现实时推送的核心技术,其流程与传统“短轮询”有本质区别,可拆解为 4 个关键步骤:
1. 传统短轮询的问题
传统短轮询的逻辑是:客户端每隔固定时间(如 1 秒)向服务器发送 HTTP 请求,询问“是否有新数据?”
- 若有新数据:服务器立即返回数据,客户端处理后,等待下一个轮询周期再次请求;
- 若没有新数据:服务器立即返回“空响应”,客户端同样等待周期后重试。
缺点:大量无效请求(无数据时的空响应)浪费带宽和服务器资源,且实时性受轮询周期限制(周期越长延迟越高,周期越短资源消耗越大)。
2. CometD 长轮询的流程
长轮询的核心优化是:服务器在没有新数据时,不立即返回响应,而是“挂起”请求,直到有新数据或请求超时,具体步骤如下:
步骤 | 客户端行为 | 服务器行为 |
---|---|---|
1 | 客户端向服务器发送 长轮询请求(HTTP POST),请求中携带 CometD 协议头(如会话 ID、订阅的事件主题),并声明“允许长轮询”。 | 服务器接收请求后,检查是否有客户端订阅的新数据(如 Salesforce 中的 RecordEvent )。 |
2 | 客户端等待服务器响应(不立即关闭连接)。 | - 若有新数据:服务器立即封装数据(按 CometD 协议格式,通常为 JSON),返回 HTTP 响应; - 若无新数据:服务器不返回响应,而是“挂起”该请求(保持 HTTP 连接打开),持续监听新数据。 |
3 | 客户端收到响应后,立即处理数据(如更新页面、触发业务逻辑)。 | 服务器在返回响应后,释放该请求的资源。 |
4 | 客户端处理完数据后,立即发起下一次长轮询请求,重复步骤 1-3,形成“持续等待-推送-再等待”的循环。 | 服务器继续监听新数据,为下一次请求做准备。 |
3. 关键细节:避免连接超时与资源泄漏
- 请求超时控制:服务器不会无限期挂起请求,通常会设置一个超时时间(如 30 秒)——若 30 秒内仍无新数据,服务器会返回一个“空响应”,客户端收到后立即发起新的长轮询请求,避免连接被网络设备(如防火墙)强制断开。
- 会话保持:CometD 通过
Client ID
维护客户端与服务器的会话(第一次请求时服务器生成Client ID
,后续请求携带该 ID),确保服务器能识别“同一个客户端”的连续长轮询请求,避免重复初始化。 - 批量推送:若在一次长轮询挂起期间有多个新数据,服务器会将数据批量封装到一个响应中返回,减少请求次数。
三、CometD 协议的核心特性(为何适合企业级场景?)
除了长轮询,CometD 还具备以下企业级必需的特性,使其在 Salesforce 等系统中被广泛采用:
- 双向通信:不仅支持服务器向客户端推送数据,客户端也可通过同一连接向服务器发送数据(如订阅/取消订阅事件、提交实时指令),实现“双向实时交互”。
- 主题订阅(Topic Subscription):客户端可通过
subscribe("/topic/xxx")
订阅特定“主题”(如 Salesforce 中平台事件的主题/_event/RecordEvent
),服务器仅向订阅了对应主题的客户端推送数据,实现“精准推送”,减少无效数据传输。 - 可靠性保障:
- 消息确认(ACK):客户端收到数据后,会向服务器发送“确认消息”,若服务器未收到确认,会重新推送数据,避免数据丢失;
- 会话重连:若网络中断,客户端可通过
Client ID
重新连接服务器,恢复之前的订阅状态,无需重新初始化。
- 兼容性:基于 HTTP/HTTPS,兼容所有支持 HTTP 的网络环境(防火墙、代理服务器等),无需额外配置端口,解决了 WebSocket 在部分企业网络中被禁用的问题。
- 扩展性:支持集群部署(多台服务器通过共享会话存储协同工作),可应对高并发场景(如 thousands 级客户端同时接收实时事件)。
四、在 Salesforce 中的应用:实时接收平台事件
Salesforce 利用 CometD 协议实现 “实时平台事件订阅”,开发者可通过 CometD 客户端(如 Salesforce 官方的 cometd-java-client
、JavaScript 客户端)实时接收 RecordEvent
、LoginEvent
等标准事件,或自定义平台事件。Salesforce 官方的 CometD Java 客户端和 JavaScript 客户端是用于实现与 Streaming API 进行交互的工具。Salesforce Streaming API 是基于 CometD 协议构建的一种服务,它允许外部系统通过建立持久连接来接收 Salesforce 平台的事件推送。有关详细代码实现,请参与我的这篇文章。
Salesforce 中使用 CometD 订阅事件的典型流程:
- 获取认证令牌:客户端先通过 Salesforce OAuth 2.0 流程获取
Access Token
(用于验证身份)。 - 建立 CometD 连接:客户端向 Salesforce 的 CometD 端点(如
https://<your-domain>.my.salesforce.com/cometd/48.0/
)发送连接请求,携带Access Token
和协议版本,服务器验证通过后返回Client ID
,建立会话。 - 订阅事件主题:客户端发送
subscribe
请求,订阅目标事件主题(如订阅RecordEvent
的主题:/_event/RecordEvent
)。 - 接收实时推送:当 Salesforce 中发生
RecordEvent
(如 Account 记录被创建),服务器会通过长轮询连接将事件数据推送给客户端,客户端处理数据(如实时更新前端页面、同步到外部系统)。 - 断开连接:客户端不再需要实时数据时,发送
disconnect
请求,关闭会话。
五、CometD vs WebSocket:为何 Salesforce 选择 CometD?
WebSocket 是另一种主流的实时通信协议,与 CometD(长轮询)的核心区别在于:WebSocket 是基于 TCP 的全双工协议,连接建立后可直接传输二进制/文本数据,延迟更低;但 CometD 基于 HTTP,兼容性更强。
Salesforce 选择 CometD 的核心原因:
- 企业网络兼容性:大量企业防火墙会禁用 WebSocket 所需的 80/443 以外的端口,或拦截非 HTTP 协议的流量,而 CometD 基于 HTTP,可无缝穿透这些网络限制;
- 成熟的可靠性机制:CometD 的消息确认、会话重连等特性,更符合 Salesforce 对“企业级数据可靠性”的要求(如避免客户数据更新事件丢失);
- 与现有 HTTP 生态集成:可直接复用 Salesforce 现有的 OAuth 认证、HTTP 权限控制体系,无需额外开发。
总结
CometD 协议通过 长轮询 机制,在 HTTP 基础上实现了“接近实时”的服务器推送,同时兼顾了可靠性、兼容性和企业级扩展性。在 Salesforce 中,它是实时接收平台事件、实现实时数据同步的核心技术,帮助开发者构建“数据变化即时响应”的业务场景(如实时客户数据更新、实时告警、实时报表)。