Salesforce Streaming API 是 Salesforce 提供的实时事件推送接口,核心功能是通过建立持久连接,让外部系统(或内部组件)实时接收 Salesforce 中的数据变更事件(如记录创建/更新、用户登录等),无需频繁轮询,从而实现“数据变化即时响应”。它本质上是基于 CometD 协议(长轮询机制)构建的企业级实时通信解决方案,广泛用于数据同步、实时监控、自动化流程触发等场景。
一、Streaming API 的核心定位与价值
传统的 Salesforce API(如 REST API、SOAP API)采用“请求-响应”模式,外部系统需主动发起请求才能获取数据,无法实时感知 Salesforce 内部的变化(例如:当客户更新了联系方式,外部 CRM 系统无法立即知晓,需定时轮询)。
Streaming API 则解决了这一痛点:
- 主动推送:Salesforce 作为“服务器端”,当特定事件发生时(如
Account记录被修改),主动将事件数据推送给已订阅的外部系统; - 持久连接:通过 CometD 协议的长轮询机制,建立“客户端- Salesforce”的持久通信通道,避免频繁无效请求,降低资源消耗;
- 事件驱动:基于“订阅-发布”(Pub/Sub)模式,外部系统只需订阅关注的“事件主题”,即可精准接收目标数据,无需处理无关信息。
二、Streaming API 支持的事件类型
Streaming API 可推送的事件覆盖 Salesforce 核心业务场景,主要分为以下几类:
| 事件类型 | 描述 | 适用场景举例 |
|---|---|---|
| 平台事件(Platform Events) | 包括标准平台事件(如 RecordEvent、LoginEvent)和自定义平台事件。 |
实时同步记录变更、监控用户登录行为 |
| 变更数据捕获(CDC Events) | 专门捕获标准/自定义对象的“数据变更”(创建/更新/删除/恢复),包含完整的字段前后值。 | 外部系统与 Salesforce 数据实时同步(如 ERP、BI 工具) |
| 推送主题(Push Topics) | 基于 SOQL 查询定义的“自定义事件主题”,仅推送符合查询条件的记录变更。 | 按业务规则筛选实时数据(如“仅推送金额>10万的 Opportunity 赢单事件”) |
| Generic Events | 无需预先定义事件结构,可动态发送自定义格式的事件,灵活性高。 | 跨系统传递非结构化的实时通知(如告警信息) |
三、Streaming API 的典型应用场景
- 实时数据同步:外部系统(如企业 ERP、BI 工具)实时同步 Salesforce 数据变更(如订单创建、客户信息更新),确保数据一致性;
- 实时监控与告警:监控关键业务事件(如高价值 Opportunity 流失、用户异常登录),实时触发告警(邮件、钉钉通知);
- 前端实时交互:Salesforce Lightning 组件或外部 Web 应用(如客户门户)实时展示数据变更(如“新工单提醒”“实时销售数据看板”);
- 跨系统自动化:当 Salesforce 发生特定事件(如合同签署),实时触发外部系统流程(如财务系统自动生成发票)。
四、核心工作原理:基于 CometD 的持久连接
Streaming API 完全依赖 CometD 协议实现持久连接和事件推送,其完整流程可拆解为 5 步,本质是“连接建立→订阅主题→事件监听→推送数据→重连维护”的循环:
下面以 JavaScript 客户端(最常用场景)和 Java 客户端为例,结合完整代码,详细拆解 Salesforce Streaming API 基于 CometD 协议的5 步流程。
通用前置准备
在开始前,需完成 Salesforce 环境配置,这是后续流程的基础:
- 创建 Connected App:
- 进入 Salesforce Setup → 搜索“App Manager”→ 点击“新建连接应用程序”。
- 填写“应用程序名称”“API 名称”,在“API(启用 OAuth 设置)”中勾选“启用 OAuth 设置”,设置“回调 URL”(如
https://localhost,测试用)。 - 在“选定的 OAuth 范围”中添加
full(全权限,测试用)或api(最小权限,生产用),保存后获取 Consumer Key(Client ID) 和 Consumer Secret。
- 获取 Salesforce 域名:
- 点击右上角用户头像 → “设置”→ 搜索“我的域名”,获取完整域名(如
https://your-domain-123.my.salesforce.com)。
- 点击右上角用户头像 → “设置”→ 搜索“我的域名”,获取完整域名(如
- 准备安全令牌:
- 若使用“密码式 OAuth 流程”,需将 Salesforce 密码与“安全令牌”拼接(如密码
abc123+ 安全令牌xyz789→abc123xyz789),安全令牌可通过“我的个人信息→重置我的安全令牌”获取。
- 若使用“密码式 OAuth 流程”,需将 Salesforce 密码与“安全令牌”拼接(如密码
一、JavaScript 客户端实现(基于 cometd.js)
步骤 1:连接建立(CometD 握手 + 认证)
核心是通过 OAuth 获取 Access Token,再携带令牌与 Salesforce Streaming API 端点建立 CometD 连接(握手),获取会话 Client ID。
1.1 引入依赖
在 HTML 中引入 CometD 客户端库(官方推荐版本 7.0.0+):
<!-- 引入 CometD 核心库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/cometd/7.0.0/cometd.js"></script>
<!-- 引入 CometD 长轮询传输层(默认已包含,显式引入确保兼容性) -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/cometd/7.0.0/cometd-long-polling.js"></script>
1.2 代码实现(连接建立)
// 1. 配置基础参数(替换为你的实际信息)
const CONFIG = {
clientId: "3MVG9fe4YXyap4urFdN_7k2Q1bXx9z8hGtR3sT5v7u8iJ0kL1mO2p", // Connected App 的 Client ID
clientSecret: "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6Q7R8S9T0U1V2W3", // Connected App 的 Client Secret
username: "user@company.com", // Salesforce 用户名
password: "abc123xyz789", // 密码 + 安全令牌
domain: "https://your-domain-123.my.salesforce.com", // Salesforce 域名
apiVersion: "59.0" // Streaming API 版本(建议用最新稳定版)
};
// 2. 获取 OAuth Access Token(密码式流程,适用于后端/测试场景)
async function getSalesforceAccessToken() {
const tokenEndpoint = `${
CONFIG.domain}/services/oauth2/token`;
const params = new URLSearchParams({
grant_type: "password",
client_id: CONFIG.clientId,
client_secret: CONFIG.clientSecret,
username: CONFIG.username,
password: CONFIG.password
});
try {
const response = await fetch(tokenEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded" },
body: params
});
if (!response.ok) throw new Error(`获取令牌失败:${
response.statusText}`);
const data = await response.json();
console.log("Access Token 获取成功:", data.access_token.substring(0, 20) + "..."); // 脱敏显示
return data.access_token; // 返回核心令牌
} catch (error) {
console.error("OAuth 认证错误:", error.message);
throw error; // 抛出错误,中断后续流程
}
}
// 3. 建立 CometD 连接(握手)
let cometdInstance; // 全局 CometD 实例,用于后续操作
async function establishCometDConnection() {
try {
// 3.1 获取 Access Token
const accessToken = await getSalesforceAccessToken();
// 3.2 初始化 CometD 实例
cometdInstance = new CometD();
const streamingEndpoint = `${
CONFIG.domain}/cometd/${
CONFIG.apiVersion}/`; // Streaming API 端点
// 3.3 配置连接(关键:携带认证头 + 长轮询参数)
cometdInstance.configure({
url: streamingEndpoint,
requestHeaders: {
"Authorization": `Bearer ${
accessToken}`, // 认证核心:Bearer Token
"Content-Type": "application/json"
},
logLevel: "info", // 日志级别:info/debug/error,调试时用 debug
maxConnectionAttempts: 5 // 最大重连次数(后续重连维护会用到)
});
// 3.4 握手(建立连接)
return new Promise((resolve, reject) => {
cometdInstance.handshake((handshakeReply) => {
if (handshakeReply.successful) {
console.log("✅ CometD 连接建立成功!");
console.log("会话 Client ID:", cometdInstance.clientId); // 服务器返回的唯一会话 ID
resolve(cometdInstance); // 连接成功,返回实例
} else {
const errorMsg = `❌ CometD 握手失败:${
handshakeReply.error?.message || "未知错误"}`;
console.error(errorMsg);
reject(new Error(errorMsg));
}
});
});
} catch (error) {
console.error("连接建立整体错误:", error.message);
throw error;
}
}
// 执行连接建立(后续步骤依赖此结果)
establishCometDConnection().then(

最低0.47元/天 解锁文章
3084

被折叠的 条评论
为什么被折叠?



