不能。Webman 默认仅支持HTTP/HTTPS协议,其App类和路由系统基于HTTP生命周期设计,无法直接监听TCP二进制协议;需绕过Webman,基于Workerman在config/process.php中注册自定义Worker进程实现。

Webman 能不能直接监听 TCP 二进制协议?
不能。Webman 默认只处理 HTTP/HTTPS 协议,它的 App 类和路由系统完全基于 HTTP 请求生命周期设计。你无法在 config/server.php 的 listen 字段里填 tcp://0.0.0.0:9501 然后期望它自动解析自定义二进制包——那会直接报错或静默失败。
真正能监听 TCP(包括二进制流)的是底层的 Workerman。Webman 只是 Workerman 的一个“HTTP 应用层封装”。所以必须绕过 Webman 的 HTTP 入口,直接基于 Workerman 写自定义进程。
如何用 Webman 项目结构启动一个 TCP 二进制服务?
核心做法:在 config/process.php 中注册一个自定义进程,handler 指向一个继承 Workerman\Worker 的类,手动实现 onConnect/onMessage/onClose。
常见错误现象:
– 启动后看不到进程日志,或提示 Class not found
– 客户端连上就断,无任何回调触发
– onMessage 收到的数据是乱码或截断(没处理粘包)
立即学习“PHP免费学习笔记(深入)”;
实操要点:
- 类必须放在
app/下(如app/TcpServer.php),命名空间为app,且需use Workerman\Worker; - 不要在类里调用
Webman\App或依赖 HTTP 相关组件(如Request、Response) -
onMessage接收的是原始$connection->recv()数据,需自行解析协议头、长度字段、处理粘包/半包 - 若需复用数据库等组件,可用
support\Db::等 Webman 提供的静态门面,但注意连接池/事务不在请求上下文里,要自己管理
为什么不能用 process/EventStreamProcess.php 处理二进制流?
process/EventStreamProcess.php 是 Webman 为 SSE(Server-Sent Events)定制的,它内部强依赖 HttpConnection 和 HTTP 响应头写入逻辑,所有输出都带 data:、id:、event: 等文本格式前缀。你往里面塞二进制数据,客户端 JavaScript 的 EventSource 会直接解析失败或丢弃。
更关键的是:SSE 协议本身是基于 HTTP 的长连接文本协议,不支持双向通信,也不允许服务端接收客户端发来的任意二进制帧——它只单向推送。所以拿它传图片、音频、加密 payload,本质上就是协议误用。
适用场景仅限:
– 后端推送纯文本状态更新(如任务进度、日志行)
– 客户端只需要 read-only 订阅,不要求响应或 ACK
二进制协议开发最容易被忽略的三个点
一是粘包问题。TCP 是字节流,没有消息边界。onMessage 触发时机 ≠ 一个完整业务包到达。你必须在接收缓冲区里按协议定义的包头(比如前 4 字节是包体长度)做分包,否则一次 recv() 可能含多个包,或一个包被拆成多次到达。
二是连接生命周期管理。HTTP 请求天然有始有终;而 TCP 长连接下,客户端可能异常断线(断电、kill -9),服务端不会立刻感知。onClose 回调可能延迟数秒甚至更久。得配合心跳(如每 30 秒发 PING 包并等待 PONG)+ Worker::$connections 遍历清理。
三是编码与调试成本。没有浏览器 DevTools 可视化抓包,得用 tcpdump + Wireshark,或在 onMessage 里加 file_put_contents('debug.bin', $data, FILE_APPEND) 保存原始字节再用十六进制工具分析。别指望 var_dump 能看清二进制内容。



















