Workerman不直接解析RFID协议,而是作为高性能数据管道:外部采集服务解析标签数据后,通过TCP/Redis推送至Workerman,再由GatewayWorker按任务组广播给多终端,确保实时协同与消息可靠投递。

Workerman 本身不直接处理 RFID 硬件通信,它只负责高性能、长连接的网络通信层。真正实现 RFID 出入库实时盘点,关键在于「Workerman 做数据管道」+「外部服务做标签采集」——不是用 Workerman 去读标签,而是让它高效接收、分发、广播 RFID 设备(如固定式读写器、手持机)上报的原始标签数据。
RFID设备数据怎么进Workerman?
固定式读写器(如 Impinj Speedway、Alien ALR-9900)或工业网关通常支持 TCP/UDP/HTTP 协议主动上报标签事件。不能指望它们直连 Workerman 的 WebSocket 或 HTTP 接口,必须做一层适配:
- 用独立进程(Python/Go/Node.js)监听读写器的原始 UDP/TCP 端口,解析 EPC 数据、RSSI、天线号、时间戳等字段
- 该进程将清洗后的结构化数据(如
{epc: "30142223A123456789012345", event: "enter", antenna: 2, ts: 1747917720})通过WorkerMan\Connection\TcpConnection::send()或GatewayWorker的sendToAll()推给 Workerman - 避免在 Workerman 主进程里做阻塞式 socket recv(),否则会卡住整个事件循环
如何用Workerman支撑多终端实时协同盘点?
当多个手持 RFID 终端(如 Zebra FX75 + Android APP)和固定通道同时上报时,Workerman 的 GatewayWorker 模式最实用:
- 每个手持终端建立一个 WebSocket 连接,绑定用户 ID 和盘点任务 ID(如
task_20260522_warehouse_a) - 后端业务逻辑收到新标签后,立刻调用
GatewayClient::sendToGroup()广播给同任务组所有终端,前端用WebSocket.onmessage实时更新已扫数量、高亮缺失资产 - 注意:不要用
sendToAll()全局广播,否则 A 仓库的盘点数据会刷屏 B 仓库的终端界面 - 需在
onConnect里用GatewayClient::bindUid()关联连接与用户,再用bindGroup()动态加入任务组
为什么不能直接用Workerman做RFID协议解析?
RFID 读写器原始协议(如 LLRP、EPCglobal)复杂且硬件强相关,Workerman 的 PHP 环境缺乏稳定、低延迟的二进制解析能力,容易出错:
- LLRP 协议含嵌套 TLV 结构、位域、可变长字段,PHP 的 pack/unpack 易误判边界
- 真实产线中读写器每秒上报数百条标签,PHP 解析耗时波动大,可能堆积 TCP 缓冲区导致丢包
- 抗金属标签在金属设备表面反射信号不稳定,需要 RSSI 滤波、去重、超时合并等逻辑,这些更适合用 Go 或 Rust 写成独立 service
- Workerman 应专注「连接管理 + 消息路由」,把协议解析下沉到专用采集服务,两者通过本地 Unix Socket 或 Redis Pub/Sub 通信
盘点结果如何保证不丢、不错、可追溯?
Workerman 不持久化数据,但能确保「每条标签事件至少被下游业务系统消费一次」:
- 采集服务将原始标签 JSON 写入 Redis Stream(
XADD rfid:stream * epc ...),并记录 offset - Workerman 的 GatewayWorker 收到消息后,先调用业务接口(如
/api/v1/inventory/scan)完成校验、比对、库存扣减;仅当 HTTP 返回 200 才向终端广播成功 - 若业务接口超时或失败,采集服务从 Redis Stream 重放未确认的消息,避免因网络抖动导致漏盘
- 所有标签事件带唯一
read_id和毫秒级ts,数据库表设计必须包含这两个字段,用于审计和差异分析
真正难的不是让标签数据“进来”,而是让每一条 EPC 在入库、出库、盘点三个场景下,都对应到正确的资产实体、货位、批次、操作人——这需要 WMS 系统的业务规则引擎兜底,Workerman 只是那个不喘气、不丢消息、不卡顿的信使。

















