Workerman 不原生支持 CoAP 协议,需基于 UdpConnection 手动解析二进制报文头、Token、Options 和 Payload;官方无 CoAP 协议类,也无成熟扩展包,低功耗场景下建议精简实现 GET/POST 基础功能。

Workerman 本身不原生支持 CoAP 协议,它没有内置 CoAP 协议类或 CoAPWorker 类。想用 Workerman 接入 CoAP 设备,必须手动实现协议层 —— 但这条路可行,且在资源受限设备上反而更可控。
为什么不能直接 new CoAPWorker()?
Workerman 的协议支持依赖于「协议类」(如 Http、WebSocket)配合 TcpConnection 或 UdpConnection 工作。而 CoAP 是基于 UDP 的二进制协议,需自行解析报文头、Token、Options、Payload,还要处理 Observe、Block-Wise、DTLS 等扩展逻辑。官方未提供 CoAP 协议类,也没有社区高成熟度的 workerman-coap 包(截至 2026 年 5 月)。
用 UdpConnection + 手动 unpack 实现 CoAP 接收
CoAP 默认端口是 5683,运行在 UDP 上,适合低功耗设备发短包。Workerman 的 UdpConnection 可直接监听该端口,接收原始二进制数据:
- 使用
socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)创建的 socket 在 Workerman 中对应UdpConnection实例 -
onMessage回调收到的$data是原始字节流,需用unpack('C*', $data)或ord($data[0])解析 CoAP 报文头(前 4 字节:Ver+T+TKL+Code) - 必须自己实现
parse_options()和decode_payload(),CoAP 的 TLV 结构(Type-Length-Value)不像 HTTP 那样有标准解析器 - 不要在
onMessage中做阻塞操作(如 file_get_contents、sleep),否则会卡住整个事件循环
示例片段(仅解析基础报文头):
$worker = new Worker('udp://0.0.0.0:5683');
$worker->onMessage = function (UdpConnection $connection, $data) {
if (strlen($data) > 6) & 0x03;
$type = ($first_byte >> 4) & 0x03;
$token_length = $first_byte & 0x0f;
$code = ord($data[1]);
// 后续还需读取 Message ID(2 字节)、Token(0–8 字节)……
};
超低功耗设备对接的关键约束
Workerman 做 CoAP Server 对电池供电设备友好,但要注意这些硬性限制:
- CoAP 客户端通常只发一次请求、等响应,不维持连接 —— 所以不用管
onConnect/onClose,专注onMessage即可 - 务必关闭日志写入磁盘(
Worker::$stdoutFile = '/dev/null'),避免 SD 卡频繁擦写影响寿命 - 禁用所有非必要组件:不加载
AsyncMysql、AsyncRedis,它们会隐式创建额外连接和定时器 - UDP 无重传机制,若业务要求可靠性,得在应用层加简单 ACK(比如返回
2.05 Content并附带请求 Token),不能依赖 CoAP 自身 QoS(它靠客户端重发) - DTLS 加密暂不可行:Workerman 的 UDP 不支持 SSL/TLS 握手,
coaps://(即 DTLS over UDP)无法直接支持
真正难的不是解析 CoAP 报文,而是把 Observe 模式、Block-Wise 分块传输、缓存控制这些可选特性在 PHP 里稳定跑起来。多数超低功耗场景其实只用到 GET/POST + 简单响应,这时手动解析前 12 字节 + Payload 就够用了 —— 其他字段先 ignore,别一上来就想做全量兼容。











