onconnect一定先于onmessage触发,因onconnect在tcp握手及协议就绪(如websocket upgrade完成)后才执行,此时连接对象已创建且readystate===1,onmessage依赖该就绪状态才能投递消息。

onConnect 一定先于 onMessage 触发,且只在连接真正就绪(readyState === 1)后才可能收到任何 onMessage。这不是“大概率”或“通常”,而是 Workerman 事件循环与 TCP 连接生命周期决定的硬性顺序。
onConnect 是连接就绪的唯一可信信号
Workerman 的 onConnect 回调在底层 socket 完成 accept、完成握手(如 WebSocket 的 HTTP Upgrade)、并成功初始化 Connection 对象后立即触发。此时该连接已可收发数据。
-
onMessage不可能在onConnect之前触发——因为连接对象尚未创建,消息无处投递 - 如果你观察到“先收到消息”,实际是服务端在连接建立后极短时间内推送了数据,而你的
onMessage监听早已注册(比如写在onConnect外),导致回调被快速调用;但事件本身仍发生在onConnect之后 - 所有对
$connection的操作(如$connection->send()、设置$connection->onMessage)都应在onConnect内或之后执行,否则可能遇到Call to a member function send() on null或静默失败
onMessage 触发依赖于连接状态和事件循环调度
onMessage 并非“一有数据就立刻执行”,它由 Workerman 的 EventLoop 在检测到 socket 可读时触发。但前提是:该连接已通过 onConnect 创建,且未被关闭或中断。
- 如果
onConnect中做了耗时同步操作(如阻塞式 DB 查询、sleep(1)),整个进程会卡住,后续所有连接的onConnect和已有连接的onMessage都会被延迟 - Workerman 默认不缓存未就绪连接的消息;若客户端在握手完成前疯狂发包,这些数据通常被内核丢弃或重置,不会积压到
onMessage -
onMessage回调中拿到的$connection是封装后的Connection实例,不是原生 resource,不能直接用fread()或stream_socket_recvfrom()
为什么有时 onConnect 像“没触发”?先别调顺序,查连接本身
所谓“onMessage 先来”或“onConnect 不执行”,90% 是连接根本没成功建立,而不是事件顺序异常。
- 检查日志里有没有
PHP Warning: stream_socket_accept(): unable to accept incoming connection或类似错误 - 确认监听地址没被占用:
netstat -tuln | grep :2346(假设你监听 2346 端口) - 如果是 Websocket 场景,浏览器控制台出现
WebSocket connection to 'ws://...' failed,说明前端连不上,onConnect根本不会进 - Workerman 启动后没有输出
New connection类日志?那问题出在 TCP 层,和onMessage无关
真正容易被忽略的点是:Workerman 的 onConnect 不代表“协议握手完成”,只代表“TCP 连接已 accept”。对于 WebSocket,协议级就绪还要等 Upgrade 响应返回;但 Workerman 的 websocket:// Worker 会在 Upgrade 成功后才触发 onConnect,所以你不需要自己判断 Sec-WebSocket-Accept ——只要进了 onConnect,就能安全地 send() 和监听 onMessage。











