不能。Workerman本身是纯网络I/O框架,不提供inotify、kqueue等文件系统事件监听能力,轮询会阻塞事件循环;可行方案是用inotifywait等独立进程捕获变更,再通过TCP/Unix Socket等IPC通知Workerman执行任务。

Workerman 能不能直接监听文件变动?
不能。Workerman 本身是纯网络 I/O 框架,不提供文件系统事件监听能力(比如 inotify、kqueue),filemtime() 轮询也不是它该干的事——这会阻塞事件循环,破坏其异步非阻塞特性。
真正可行的路径是:用独立进程(如 inotifywait 或 chokidar)捕获文件变化,再通过 IPC(如 Unix Socket、Redis Pub/Sub 或 TCP)通知 Workerman 进程执行编译逻辑。
推荐方案:inotifywait + Workerman TCP 通信
Linux 下最轻量、低依赖的组合。关键点在于避免 fork 阻塞主进程,且确保消息可靠送达。
-
inotifywait启动为后台常驻进程,监听指定目录(如src/),触发时只发送一行消息(如change:app.js)到 Workerman 的 TCP 端口 - Workerman 启一个
Worker监听本地 TCP(如127.0.0.1:8081),用onMessage接收并分发编译任务 - 不要在
onMessage里直接调用exec()编译命令——会阻塞整个 Worker;改用process扩展或shell_exec()+pcntl_fork()派生子进程 - 注意
inotifywait默认一次只输出一条事件,加-m参数才能持续监听,加-e modify,create,delete明确事件类型,避免误触发
PHP 侧如何安全执行编译命令?
Node.js 项目常用 npm run build,但 PHP 进程直接调用有风险:环境变量缺失、工作目录错误、超时卡死。
- 始终用绝对路径调用命令,例如
/usr/bin/npm而不是npm - 显式设置
cwd和env:['PATH' => '/usr/local/bin:/usr/bin', 'NODE_ENV' => 'production'] - 必须设超时(
timeout参数),否则一个卡住的webpack会让整个监控失效 - 捕获
stderr并记录,否则编译失败你根本看不到报错——proc_open()比exec()更可控 - 避免并发多次触发编译:收到变更后先检查是否有正在运行的编译进程(可用
file_put_contents('build.lock', getmypid(), LOCK_EX)实现简单互斥)
为什么不用 Workerman 内置定时器轮询?
有人试过每秒扫一遍 scandir() + filemtime(),短期能跑,但很快暴露问题:
- 1000 个文件下,每次扫描至少 50ms,CPU 持续占用,Workerman 处理网络请求的延迟明显上升
- 修改时间精度是秒级,同一秒内多次保存会被合并成一次,漏触发
- 无法区分“内容修改”和“属性修改(chmod)”,容易误编译
- macOS / Windows 下
filemtime()行为不一致,跨平台维护成本高
inotify/kqueue 是内核级事件,零延迟、零遗漏、零轮询开销——这才是监控服务该有的样子。

















