Workerman 4.0.34 不支持协程,必须用回调处理所有 I/O 操作;同步调用如 file_get_contents() 或 PDO 会阻塞 event-loop 导致进程假死;Redis、HTTP、MySQL 均需异步回调实现,无 await 或同步客户端支持。

Workerman 4.0.34 中协程模式不可用,必须用回调
Workerman 4.0.34 是纯异步事件驱动版本,不内置协程运行时,所有 I/O 操作(如 Redis、HTTP、MySQL)都必须通过回调函数处理,否则会阻塞 event-loop 导致服务假死。
直接在 onMessage 回调里写 file_get_contents() 或 new PDO() 这类同步操作,【整个 worker 进程将被锁死,无法响应其他连接】。这不是性能问题,而是架构限制——4.0.34 的 event-loop 是单线程单消费者模型,没有协程调度层。
Redis 操作:回调写法(唯一可行方式)
方法一:使用 workerman/redis 客户端 + 回调函数
1. 安装依赖:composer require workerman/redis
2. 在 onWorkerStart 中初始化 Redis 实例,并声明为 global 变量供后续使用
3. 在 onMessage 中调用 $redis->get() 时,必须传入匿名函数作为第三个参数,结果在回调中获取,不能直接赋值给变量
这一步不能省略回调参数,否则 get() 会返回 null 或抛出异常,因为底层是异步非阻塞的;你写的代码看起来像在“等待”,其实只是注册了一个将来被执行的函数。
HTTP 请求:只能用 stream_socket_client + 手动解析
Workerman 4.0.34 没有 http-client 组件,也没有内置 await 支持,想发 HTTP 请求只能自己封装 socket 流。
① 创建非阻塞 TCP 连接:$socket = stream_socket_client('tcp://api.example.com:80', $errno, $errstr, 3, STREAM_CLIENT_ASYNC_CONNECT);
② 设置超时并监听可写事件:$worker->onWorkerStart = function($worker) use ($socket) { Worker::$eventLoop->onWritable($socket, function($socket) { fwrite($socket, "GET /data HTTP/1.1\r\nHost: api.example.com\r\n\r\n"); }); };
③ 接收响应需监听可读事件,手动解析 HTTP 头与 body 分界,错误处理要覆盖 Connection reset、timeout、partial read 等全部边界情况
这比写 curl 脚本还麻烦,但这是 4.0.34 下唯一不卡死的方式。试图用 file_get_contents() 或 Guzzle 同步客户端,【会立即冻结当前 worker,直到请求完成才释放 event-loop】。
MySQL 查询:必须用 workerman/mysql + 回调链
方法一:基于 workerman/mysql 的异步查询回调链
require_once 'vendor/autoload.php';
$db = new Workerman\Mysql\Connection('127.0.0.1', 3306, 'user', 'pass', 'test');
$db->query("SELECT * FROM users WHERE id = 1", function($rows, $error) use ($connection) { if ($error) { $connection->send("DB error: " . $error); return; } $connection->send(json_encode($rows)); });
注意:不能把 $db->query() 的结果直接 echo 或 return,它返回的是 void;所有数据处理逻辑必须包裹在回调函数内部,且该回调可能在数毫秒后执行,也可能因网络重试延迟几百毫秒。











