composer本身不发事件,无法直接websocket推送;必须通过git webhook触发构建脚本,再经redis pub/sub广播至websocket客户端,且需健康检查确保包真正可用。

不能直接用 WebSocket 推送 Composer 镜像包版本更新通知——因为 Composer 本身不发事件,也不暴露实时钩子。你真正能监听和触发推送的,是 Git 仓库(如 GitHub/GitLab)的 push 或 create tag 事件,再通过 Webhook 转发给后端服务,最后由该服务主动向已连接的 WebSocket 客户端广播。
为什么不能在 Composer install/update 时触发 WebSocket 推送
Composer 是纯客户端工具,运行在开发者本地或 CI 环境中,它不会反向调用你的服务器。所谓“镜像包更新”,本质是私有仓库索引(如 Satis 或 Private Packagist)被重新构建了——而这个构建动作,必须由外部事件(比如 Git 推送)驱动。
-
composer install和composer update不产生服务端可观测行为 - 没有 Composer 原生 hook、event 或 callback 可供监听
- 试图在
post-update-cmd中发 HTTP 请求到自己的 WebSocket 服务?不可靠:该脚本运行环境不可控(本地?CI?权限?网络策略?),且无法知道哪些客户端“关心这个包”
正确链路:Git Webhook → 构建脚本 → Redis Pub/Sub → WebSocket 广播
这是目前最稳定、可落地的架构,尤其适合 Satis 类静态镜像服务。关键点不是“谁触发”,而是“谁广播”。以 webman-push-server(v3.2.2)为例:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- GitHub 配置 Webhook,目标 URL 指向你部署的
webhook.php(需公网可访问、带签名验证) -
webhook.php收到请求后,校验X-Hub-Signature-256,解析出repository.name和ref(如refs/tags/v1.2.0) - 脚本执行
satis build,成功后向 Redis 的频道composer:package:update发布一条 JSON 消息:{"package": "acme/auth", "version": "v1.2.0", "timestamp": 1718629800} -
webman-push-server的RedisSubscribeProcess进程已订阅该频道,收到后调用$this->broadcast()向所有在线客户端(或按 channel 过滤)推送 - 前端 WebSocket 客户端监听
package:update事件,更新 UI 提示:“acme/auth 已发布 v1.2.0”
前端如何只订阅自己关心的包
别让所有客户端接收全部包更新。WebSocket 服务端应支持「频道订阅」机制,前端在连接后主动加入特定频道:
- 连接建立后,客户端发送消息:
{"type":"subscribe","channel":"package:acme/auth"} - 服务端将该
Session加入对应 Redis Hash(如ws:subs:package:acme/auth),后续只向该 Hash 中的 Session 广播 - 避免用全局
broadcast(),否则一个包更新会推送给所有用户,浪费带宽且无意义 - 频道命名建议统一前缀,如
package:{vendor}/{name}或tag:{repo}:{tag},便于运维排查
容易忽略的坑:构建完成 ≠ 包已可用
Satis 构建是原子操作,但文件写入磁盘、CDN 缓存刷新、DNS TTL 等环节仍有延迟。直接推送“已发布”可能误导用户:
- 不要在
satis build命令返回即刻推送,加一层健康检查:用curl -I https://packages.example.com/acme/auth/1.2.0/composer.json确认 HTTP 200 - 若使用 CDN,推送消息里应包含
"cdn_ready": false,等 CDN hook 回调后再补发一次"cdn_ready": true - 前端收到推送后,不要立刻禁用
composer update按钮,加个 3 秒倒计时或手动刷新提示更稳妥
真正的难点不在 WebSocket 连接本身,而在于如何把「Git 事件 → 索引构建 → 文件就绪 → 用户可见」这条链路上每个环节的状态都对齐。漏掉任一环,通知就变成噪音。










