用workerman搭建物联网通信服务的核心是利用php常驻进程稳定处理海量设备mqtt长连接,避免http轮询;需php≥7.4并启用pcntl/posix扩展,通过composer install workerman/workerman:^4.0 workerman/mqtt官方扩展,编写含server监听的mqtt_server.php,以php mqtt_server.php start -d后台启动,配合mosquitto_pub验证连通性,支持esp32、树莓派及微信小程序等多端接入。

用Workerman搭建物联网通信服务,核心是让PHP常驻进程能稳定处理海量设备的MQTT长连接,而不是依赖传统HTTP轮询。你不需要重写协议解析器,也不必纠结Node.js或Go——Workerman配合官方mqtt扩展,5分钟就能跑通一个可商用的轻量级消息中台。
安装必要组件
先确保PHP环境满足最低要求:PHP ≥ 7.4、已启用pcntl和posix扩展。运行php -m | grep -E "pcntl|posix"确认,缺一不可,否则Worker无法守护进程运行。
执行命令安装Workerman主框架和MQTT扩展:
composer require workerman/workerman:^4.0 workerman/mqtt
【必须指定workerman/mqtt而非php-mqtt等第三方库】——只有这个官方扩展能直接暴露MQTT\Server类,且与Workerman事件循环深度耦合;其他库多为客户端实现,强行用于服务端会导致连接泄漏或QoS失效。
编写最小可用MQTT服务端
新建文件mqtt_server.php,粘贴以下代码:
use Workerman\MQTT\Server;
$server = new Server('0.0.0.0', 1883);
$server->onConnect = function ($connection) {
echo "Client connected: {$connection->getRemoteIp()}\n";
};
$server->onPublish = function ($connection, $topic, $payload, $qos) {
echo "Received on {$topic}: {$payload} (QoS={$qos})\n";
};
$server->listen();
这一步不能省略$server->listen()调用。Workerman\MQTT\Server不是Worker子类,不调用listen()就只是个空对象,端口根本不会被绑定——很多开发者卡在这步,用netstat查不到监听,却以为是防火墙问题。
启动并验证服务
第一步:后台启动服务
php mqtt_server.php start -d
第二步:本地测试连通性
mosquitto_pub -h 127.0.0.1 -p 1883 -t 'sensor/temperature' -m '26.5'
第三步:观察终端输出是否打印接收日志。若看到Received on sensor/temperature: 26.5 (QoS=0),说明服务已就绪。
注意:-d参数必须带上,否则服务前台运行,关闭SSH终端即终止进程。生产环境务必加-d,别信“先试一下不加”的侥幸心理——曾经有客户因漏掉这个参数,凌晨三点设备全部离线。
对接真实物联网设备
方法一:ESP32使用Arduino MQTT库直连
设置WiFi后,用client.connect("esp32_001", "username", "password")连接mqtt://your-server-ip:1883,无需TLS证书(默认明文)。订阅cmd/#主题,发布数据到sensor/#即可被服务端捕获。
方法二:树莓派Python设备端
安装paho-mqtt:pip3 install paho-mqtt,然后用标准connect→subscribe→loop_forever流程接入,主题名保持与PHP服务端回调中处理逻辑一致。
方法三:微信小程序IoT SDK(需HTTPS+TLS)
此时需修改服务端监听为SSL模式:将new Server('0.0.0.0', 1883)改为new Server('ssl://0.0.0.0:8883', ['ssl' => ['local_cert' => '/path/to/cert.pem', 'local_pk' => '/path/to/key.pem']]),否则小程序会因非安全协议拒绝连接。











