监听地址写死为127.0.0.1导致外网无法连接,必须改为0.0.0.0并完整重启服务;否则ss -tuln查不到有效监听,telnet报connection refused,且热重载无效。

监听地址写成 127.0.0.1 导致外网连不上
Workerman 启动后 netstat 查不到端口,telnet 直接报 Connection refused,八成是监听地址写死了。比如:new Worker('tcp://127.0.0.1:2345') 或 new Gateway('websocket://127.0.0.1:8080') ——这只会响应本机回环请求,服务器真实 IP 收不到包。
必须改成:new Worker('tcp://0.0.0.0:2345') 或 new Gateway('websocket://0.0.0.0:8080')。改完不能只 php start.php reload,热重载不生效,得完整重启:php start.php stop && php start.php start。
重启后立刻验证:ss -tuln | grep :2345。如果输出仍是 127.0.0.1:2345,说明代码没生效,或被其他地方覆盖(比如配置文件、环境变量、多个 Worker 实例中某一个漏改)。
Worker 构造参数里直接指定协议和端口
Workerman 没有独立配置文件,端口绑定靠 PHP 代码里的构造参数。常见写法:
-
new Worker('tcp://0.0.0.0:2345'):纯 TCP 服务 -
new Worker('http://0.0.0.0:8080'):HTTP 协议,自动解析请求头 -
new Worker('websocket://0.0.0.0:2346'):WebSocket 协议,需配合前端 ws 连接 -
new Worker('text://0.0.0.0:2015'):原始文本流,适合自定义协议
注意协议名必须小写,且冒号后紧跟 //;IP 和端口之间不能有空格;端口号必须是整数,不能带引号。
低端口(如 80、443)绑定失败但不报错
Linux 下普通用户无法绑定 1024 以下端口,Workerman 进程会静默失败:不监听、不报错、日志也常为空。现象就是 ss -tuln 看不到端口,ps aux | grep workerman 却能看到进程在跑。
解决方法只有两个:
- 用 root 启动(不推荐生产环境)
- 改用高位端口(如
8080、8443),再由 Nginx 反向代理转发(推荐)
别试图用 setcap 给 PHP 加权限,Workerman 的多进程模型会让该方式不稳定。
多端口监听要避免 Address already in use
如果想让一个 Workerman 进程同时监听 HTTP 和 WebSocket,不能在同一个 Worker 实例上调两次 listen()——它不支持复用单个 socket 对象。
正确做法是创建多个独立实例:
$http_worker = new Worker('http://0.0.0.0:8080');
$ws_worker = new Worker('websocket://0.0.0.0:2346');
// 分别设置 onMessage 等回调
Worker::runAll();
若多个进程要监听同一端口(比如负载均衡场景),必须显式开启 reusePort:$worker->reusePort = true;,否则第二个进程启动时直接报错。
端口配置看着简单,但实际卡点都在细节:地址写死、重启不彻底、权限忽略、多实例覆盖——这些地方一漏,服务就“看似运行实则失联”。











