Webman自定义进程必须继承support\Process、放app/Process/目录、实现onWorkerStart,不可直接extends Workerman\Worker;需在config/process.php配置,监听型进程要调用listen(),跨进程通信须用Redis等外部存储。

Webman里怎么用Workerman的自定义进程
Webman不是Workerman的“子集”,而是基于它构建的HTTP框架,所以所有Workerman原生能力都可用,只是默认不暴露。关键在于别把自定义进程写进Webman的HTTP生命周期里——它必须独立启动、独立管理。
常见错误是试图在app/service里new一个Worker然后调用run(),结果进程卡死或报Fatal error: Cannot declare class Worker——因为Webman启动时已加载过Workerman类,重复加载会冲突。
- 新建
process/modbus_worker.php,直接require_once __DIR__.'/../vendor/autoload.php',然后$worker = new Worker('tcp://0.0.0.0:502');不要include到控制器或中间件中 - 在
config/process.php里注册:返回数组['modbus_worker' => ['command' => 'php process/modbus_worker.php']],Webman启动时自动拉起该进程 - 自定义进程里不能用
$request或$response对象,它们只存在于HTTP上下文;改用Worker::$pid和Connection原生API操作socket - 若需与Webman共享数据(比如设备状态),优先用
Redis或pcntl_shmop,避免文件锁或全局变量竞争
为什么Webman的异步I/O不能直接套用Swoole协程写法
Webman底层用的是Workerman的事件循环,不是Swoole的协程调度器。你写Co::sleep(1)或go(function(){})会直接报错Call to undefined function Co::sleep()——因为Swoole扩展根本没装,也没被加载。
Workerman v5虽支持Fiber,但Webman默认不启用协程模式,且生态组件(如PDO、Redis客户端)多数未适配协程上下文切换。强行开启会导致连接泄漏或超时异常。
- 想做异步数据库查询,用
workerman/mysql或amphp/mysql这类真正基于事件循环的驱动,而不是改写Laravel的DB::table()->get() -
file_get_contents()、curl_exec()这类同步函数永远阻塞当前Worker进程,必须替换成Workerman\Connection\TcpConnection::send()+ 回调,或封装成Promise - Webman自带的
support/Async工具类只包装了部分基础操作(如Async::dnsLookup),别指望它能自动转换任意同步代码
Webman监听非HTTP端口时常见的Permission denied错误
Linux下绑定1024以下端口(如Modbus的502、SNMP的161)必须root权限,但Webman生产环境严禁用root运行。这不是配置问题,是操作系统级限制,硬改start.php里的用户参数没用。
更隐蔽的问题是:即使你用sudo php start.php start绕过权限检查,Webman主进程以root启动后,子Worker进程仍可能因user配置被降权,导致TCP Worker无法真正监听端口。
- 正确做法是用
setcap给PHP二进制文件授权:sudo setcap 'cap_net_bind_service=+ep' /usr/bin/php,之后普通用户就能绑定低号端口 - 或者改用端口转发:Nginx监听80,反向代理到Webman内部的高号端口(如8080),再由Webman的自定义进程监听502并转发请求——但Modbus TCP不能走HTTP代理,此方案仅适用于HTTP/HTTPS服务
- 检查
Worker::$user是否被意外覆盖:Webman的config/app.php里'user' => 'www-data'会传递给所有Worker,包括自定义进程,必须在modbus_worker.php里显式重置为Worker::$user = ''(空字符串表示不降权)
Workerman v5的Fiber特性在Webman里怎么安全启用
Fiber本身是PHP 8.1+的底层机制,Workerman v5用它重构了事件循环,但Webman官方文档至今没提供开箱即用的协程开关。盲目启用Worker::$useFiber = true会导致中间件顺序错乱、Session失效、甚至Worker进程静默退出。
真正稳定的做法是只在明确需要协程的自定义进程中启用,且避开Webman核心链路。HTTP请求处理仍走传统回调模型,保证兼容性。
- 在
process/modbus_worker.php顶部加Worker::$useFiber = true;,并在onMessage回调里用go(function(){...})启动协程处理CRC校验或寄存器读写 - 禁用所有依赖
yield的第三方库(如旧版reactphp/http),它们与Fiber不兼容;改用amphp/http-server等明确标注Fiber支持的包 - 协程内禁止调用
exit()、die()或触发致命错误,否则整个Worker进程崩溃;改用throw new Exception()并用try/catch捕获 - Webman的
app/controller里完全不要碰Fiber相关API——控制器本质是同步执行上下文,协程在这里既无意义又危险


















