webman 默认不支持 unix socket,因其http服务层基于workerman worker封装,而内置httpserver仅适配tcp流式连接与标准http头解析,未实现unix socket地址解析和绑定逻辑。

Webman 本身不直接支持监听 Unix Socket,必须通过自定义 Worker 进程 + Workerman 原生 API 实现。 官方 HTTP Server(Worker('http://...'))只接受 TCP 地址,硬塞 unix:///tmp/webman.sock 会报错 Invalid address 或直接启动失败。
为什么 Webman 默认不支持 Unix Socket?
Webman 的 HTTP 服务层是对 Workerman Worker 类的封装,而其内置的 HttpServer 协议解析器依赖 TCP 流式连接和标准 HTTP 头解析逻辑。Unix Socket 虽然底层兼容 AF_UNIX,但协议栈不经过网络层,Workerman 的 HttpServer 并未做适配 —— 它压根没实现对 socket 文件路径的地址解析和绑定逻辑。
常见错误现象:
- 在
start.php中写new Worker('http://unix:///tmp/app.sock')→ 启动时报PHP Warning: Invalid address - 尝试用
new Worker('unix:///tmp/app.sock')→ 启动成功但无法处理 HTTP 请求,因为没挂载HttpServer - 误以为配置
config/server.php的host改成路径就能生效 → 完全无效,该配置仅影响 TCP 绑定
如何让 Webman 实际监听 Unix Socket?
核心思路:绕过 Webman 的 HTTP Server 封装,自己用 Workerman 原生方式创建一个 Worker 实例,手动绑定 Unix Socket,并注册 onMessage 回调来解析 HTTP 请求(或走更轻量的纯文本/JSON 协议)。
实操建议:
- 在
app/Process/UnixSocketServer.php中定义自定义进程类,继承Workerman\Worker - 在
onWorkerStart中调用socket_create(AF_UNIX, SOCK_STREAM, 0)、socket_bind()、socket_listen() - 用
stream_socket_accept()或socket_accept()接收连接,再用stream_get_contents()读取完整 HTTP 请求体 - 手动解析
GET /path HTTP/1.1和 headers,调用 Webman 的Application实例转发请求(需复用路由和中间件) - 注意:Unix Socket 文件路径(如
/tmp/webman.sock)启动前必须确保父目录可写,且旧文件要unlink()清理,否则bind()失败
Unix Socket 通信时要注意的权限与清理问题
Unix Socket 是文件系统对象,不是网络端口,所以权限模型完全不同:
-
chmod 666 /tmp/webman.sock很常见,但生产环境应限制为600或所属用户组可读写 - 如果 Webman 主进程以
www-data用户运行,而客户端(如 Nginx)以nginx用户运行,两者需同组,且 socket 文件组权限设为g+rw - 进程异常退出时,
/tmp/webman.sock文件不会自动删除 → 必须在onWorkerStop或register_shutdown_function中显式unlink() - 客户端连接后未正确
close(),可能导致 socket 文件句柄残留,表现为“Address already in use”但lsof -U查不到占用进程
真正麻烦的不是怎么绑上 Unix Socket,而是怎么安全地复用 Webman 的请求生命周期(中间件、Session、CSRF 验证等)。如果你只是想提升 Nginx ↔ PHP 的通信效率,直接用 php-fpm.sock 更省心;非要 Webman 自己暴露 Unix Socket,就得自己扛协议解析和生命周期管理——这点容易被文档忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











