PAYATHON 2026

Google Meet 插件引入 CoDoingClient 后无法初始化,回滚仍无效

数据小陈

结论

现有信息不足以认定 supportsCollaboration 触发了无法回滚的持久状态,也无法将故障直接归因于 Meet 的 manifest 缓存。建议先检查 Meet 实际加载的 deployment、侧边栏 iframe 请求和 SDK 会话建立过程。

直接打开 sidePanelUrl 能运行,说明页面在独立标签页中可以访问。iframe 嵌入、身份验证和 Meet SDK 握手是否正常,仍需单独验证。没有 Angular 日志时,也要先排除 Console 过滤和执行上下文选错的情况。

supportsCollaboration 是否是必需配置?

Google 官方公开的 Meet 部署示例没有列出 supportsCollaboration。Co-Doing 接入文档通过 AddonSession.createCoDoingClient() 创建客户端,也没有把添加该字段列为接入步骤。因此,不应将它视为启用 CoDoingClient 的必要开关。参见部署指南和Co-Doing 接入指南。

这些文档没有说明该字段在所有环境中如何被处理,也不足以证明它曾导致持久状态损坏。故障发生在这次变更之后,可以作为排查线索,但还不足以确定因果关系。

你已经撤销配置和代码,并重建了 HTTP deployment。接下来应核实运行时实际使用的内容,避免重复同样的回滚操作。

先确认 Meet 加载了哪个部署

在对应 Google Cloud 项目的 Workspace Marketplace SDK 中检查:

  1. HTTP deployments 中的目标 deployment 是否保存了预期配置。
  2. App configuration 的 App integration 是否选择了正确的 HTTP deployment。
  3. 用于测试的 Google 账号是否安装了预期的测试部署,当前打开的插件入口是否对应目标应用。

官方部署流程要求在 App configuration 中选择 HTTP deployment,也支持从 HTTP deployments 页面为当前用户安装测试部署。创建新 deployment 后,要核对这两条使用路径,不能只确认商店条目已经重新发布。参见部署与测试流程。

原配置中的 sidePanelUrl 和 addOnOrigins 使用相同的 origin,从所示字符串看没有明显不匹配。仍需检查真实地址、端口和重定向后的地址。Meet 要求相关 origin 使用 HTTPS 并列在 addOnOrigins 中;iframe 内导航涉及的其他 origin 也需要满足这些要求。参见插件安全要求。

在 Angular 启动前检查加载过程

打开 Meet 页面后,先打开 Chrome DevTools,再启动插件:

  • 在 Console 和 Network 中启用 Preserve log,保留失败前的记录。
  • 清除 Console 文本过滤,显示各日志级别;检查是否启用了只显示当前上下文的选项,并选择插件 iframe 对应的执行上下文。参见Console 功能说明。
  • 在 Network 中查找实际的侧边栏文档请求,核对完整 URL、状态码、重定向链和响应正文。
  • 检查 Angular bundle 和 meet.addons.js 是否成功返回,以及是否出现脚本请求返回 HTML、资源 404、身份验证失败或 CSP 拦截。

可根据观察结果缩小排查范围:

观察结果优先检查
没有看到侧边栏文档请求deployment 绑定、安装入口、Meet 页面错误
文档请求跳到登录页或返回 401/403iframe 场景下的认证和访问控制
文档被拒绝嵌入Content-Security-Policy、X-Frame-Options
文档成功但脚本加载失败静态资源路径、缓存和构建产物
脚本执行但会话创建失败SDK 错误、项目编号和启动超时

frame-ancestors 决定哪些父页面可以嵌入当前页面。即使页面能独立打开,也要确认 Meet 是否被允许嵌入。应根据实际拒绝信息调整策略。参见MDN 的 frame-ancestors 说明。

分段记录 SDK 初始化,并检查超时

可以先在 HTML 中、Angular 脚本之前加入诊断代码。如果页面的 CSP 禁止内联脚本,应使用符合现有 CSP 的独立脚本文件:

console.info('[meet-addon] document script started');

window.addEventListener('error', (event) => {
  console.error('[meet-addon] error', event);
}, true);

window.addEventListener('unhandledrejection', (event) => {
  console.error('[meet-addon] unhandled rejection', event.reason);
});

随后在现有 SDK 已加载的前提下,分步记录初始化过程。以下示例应在 Meet 内运行,CLOUD_PROJECT_NUMBER 替换为目标 Google Cloud 项目的项目编号:

async function initializeMeetAddon() {
  try {
    console.info('[meet-addon] creating session');
    const session = await window.meet.addon.createAddonSession({
      cloudProjectNumber: 'CLOUD_PROJECT_NUMBER'
    });

    console.info('[meet-addon] session created');
    const client = await session.createSidePanelClient();
    console.info('[meet-addon] side panel client created');
    return client;
  } catch (error) {
    console.error('[meet-addon] initialization failed', error);
    throw error;
  }
}

官方文档说明,调用 createAddonSession() 建立会话是插件完成加载的信号。开发工具文档还要求页面在默认的 10 秒时间内实例化会话并完成导航。应尽早建立会话,将机器人连接、SDP 交换和音频录制等耗时操作放在会话建立之后。参见SDK 快速入门和开发工具说明。

调试时,可在 Meet 顶层页面的 Console 中、打开插件之前临时执行:

devtools.meet.addons.suppressHeartbeatTimeout();

调试结束后恢复:

devtools.meet.addons.resetHeartbeatTimeout();

如果关闭超时后能继续观察到初始化过程,应记录卡住的步骤和耗时。该操作用于诊断,不能代替修复启动延迟。

如何判断是不是缓存问题?

Google 官方提醒,应用的缓存策略可能导致用户延迟收到更新,用户可能要手动清理缓存或等待缓存过期才能看到新版本。这项说明针对应用缓存,不能据此断言 Meet 会长期缓存 manifest,也不能推断 deployment 有固定的缓存刷新时间。参见维护最佳实践。

建议用实际响应验证:

  1. 给应用加入可识别的构建标记,比较 Meet iframe 与独立标签页实际拿到的 HTML、JavaScript 文件名和内容。
  2. 在 DevTools 打开期间禁用浏览器缓存后复测,检查响应的 Cache-Control、ETag,以及资源是否来自缓存。
  3. 如果应用注册了 Service Worker,检查它是否仍提供旧资源;普通网络缓存开关不一定排除这条路径。
  4. 核对 Cloud Run 当前承接流量的 revision。Cloud Run 支持多个 revision 分流,回滚代码后仍应确认流量指向。参见Cloud Run 流量管理文档。

必要时,可将同一构建部署到新的测试服务,并同步更新 sidePanelUrl 和 addOnOrigins 进行对照。即使新地址恢复正常,也只能说明故障与原地址关联的某个环节有关,仍需比较缓存、响应头、认证和流量配置,不能直接认定是 Cloud Run 缓存。

拿到侧边栏文档请求、实际构建标记和 createAddonSession() 的执行结果后,通常可以判断故障发生在页面加载、资源执行还是 SDK 会话建立阶段,再恢复 CoDoingClient 和音频链路逐项验证。

备注:内容仅供参考。