yii2本身不提供websocket服务,所谓“yii2实现实时消息推送”,本质是让yii2负责业务逻辑,再由独立的websocket进程(如workerman、swoole)负责长连接管理与消息中转;workerman是最稳妥的集成方案,推荐复用其模型和数据库组件,在worker::onworkerstart中初始化轻量application实例,避免每次消息重建;站内信推送推荐使用web-msg-sender sdk,通过php yii web-msg-sender-service/start启动,默认监听2120/2121端口;ratchet需cli启动且不走yii路由,其单线程模型禁用耗时操作;推送必须从业务层显式触发,如订单保存后调用sendtouid,而非依赖框架自动感知或数据库轮询。

Yii2 本身不提供 WebSocket 服务,所谓“Yii2 实现实时消息推送”,本质是让 Yii2 负责业务逻辑(比如用户认证、消息存库、权限校验),再由独立的 WebSocket 进程(如 Workerman、Swoole)负责长连接管理与消息中转。两者分工明确,不能混用生命周期。
Workerman 是最稳妥的集成方案
它纯 PHP 编写、无扩展依赖、部署简单,适合大多数 Yii2 项目。关键不是把 Yii2 “塞进” WebSocket,而是复用其模型和数据库组件:
- 在
Worker::onWorkerStart中初始化一个轻量yii\base\Application实例(只加载db、models等必要组件),避免每次消息都重建应用 - 在
onMessage回调里调用User::findOne()或触发自定义事件,但绝不执行$app->run()或路由逻辑 - 每个 Workerman 子进程持有独立的 Yii 实例和 DB 连接——这是正常设计,不是 bug
站内信推送推荐用 web-msg-sender
这是 Workerman 官方维护的开箱即用 SDK,专为消息广播/单推设计,比手写更稳定:
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
- 通过 Composer 安装:
"kriss/yii2-web-msg-sender": "*" - 配置组件(
web.php):'webMsgSender' => ['class' => \kriss\webMsgSender\WebMsgSender::class] - 启动命令:
php yii web-msg-sender-service/start(默认监听 2120 推送端口 + 2121 API 端口) - 后端发消息只需一行:
WebMsgSender::getComponent()->getSender()->sendToUid($uid, '新消息内容')
别踩 Ratchet 的常见坑
Ratchet 虽轻量,但在 Yii2 环境下容易出错:
- 必须用 CLI 启动(如
php chat-server.php),绝不能走index.php入口,否则 PSR-7 中间件会破坏 WebSocket 握手 - Ratchet 自己监听端口(如
ws://domain:8080),不走 Yii 的 URL 路由,'chat' => 'chat/index'这类配置无效 - 它是单线程阻塞模型,
onMessage里做耗时查询(如 JOIN 多张表)会卡死整个服务
推送逻辑要从业务层显式触发
实时性不是框架自动感知的,而是靠“谁改数据谁通知”:
- 用户提交订单 → Yii2 Controller 保存订单 → 主动调用
WebMsgSender::sendToUid()或向 Workerman 内部端口发通知 - 不要指望数据库变更自动触发推送;也不要让 WebSocket 进程去轮询数据库——高延迟且伤性能
- 若需跨服务通知(如微服务架构),可用 Redis Pub/Sub 或 HTTP API 告知 WebSocket 服务端










