Workerman自定义协议可配合UDP使用,但需适配其无连接特性:input方法基本无效,decode/encode用于单报文解析与格式化,不可复用TCP协议类中的状态依赖逻辑。

支持,但需注意实现方式与 TCP 有本质区别。
UDP 场景下自定义协议的核心限制
Workerman 的自定义协议机制(通过 decode、encode、input 方法)本身是协议层抽象,不绑定传输层。因此从框架设计上,它可配合 UDP Worker 使用。但关键在于:UDP 是无连接、无会话状态的协议,不支持“粘包/分包”这类 TCP 特有概念。所以你定义的 decode 方法不会像在 TCP 中那样被反复调用以拼接完整帧;每次 onMessage 触发时,收到的就是一个独立 UDP 数据报(最大约 64KB,受 IP 层限制),天然边界清晰。
- 你仍可编写自定义协议类,用于解析该单个数据报的结构(如头部长度+JSON 载荷、二进制魔数+版本+body 等)
- encode 方法可用于统一格式化响应数据,再通过 $connection->send() 发回
- 但 input 方法在 UDP 中基本无实际用途——它本用于 TCP 流中识别包起始,而 UDP 每次收包已是完整单元
正确使用自定义协议 + UDP 的写法
不能直接把为 TCP 编写的协议类原样套用到 UDP 上。必须适配无连接特性:
- 协议类中避免依赖连接上下文(如 session、connection id 缓存等),因 UDP 的 $connection 是临时对象,不持久
- 所有地址信息(IP+端口)仅能从 $connection->getRemoteAddress() 获取,且只在 onMessage 当次有效
- 若需“主动发给某客户端”,不能遍历 $worker->connections(它对 UDP 始终为空),而要自行记录地址或使用广播/组播原生 socket
- 示例协议类只需专注:收到原始 $data → 解析出业务指令和参数 → 返回结构化响应数组 → encode 成字节流
为什么不推荐强行复用 TCP 协议类
常见误区是沿用带心跳保活、序列号校验、重传逻辑的 TCP 自定义协议,直接丢进 UDP Worker。这会导致:
- 心跳包无法被对方识别(因 decode 可能误判格式)
- 重传机制失效(UDP 本身不保证送达,框架也不提供 ACK 回调)
- 连接状态管理代码冗余甚至引发 Notice 错误(如访问不存在的 $connection->id)
- 性能无增益,反而增加解析开销
更实用的替代方案
对于典型 UDP 场景(如设备发现、实时音视频、轻量指令交互),建议:
- 直接在 onMessage 回调里做简单解析(如 json_decode($data, true) 或 unpack),不引入协议类
- 若需复用逻辑,提取纯函数式解析器(如 parseUdpPacket($raw)),而非继承 Workerman\Protocols\ProtocolInterface
- 对可靠性要求高的场景,应在应用层补足:时间戳+序列号+幂等判断,而非依赖协议框架

















