UDP协议无连接,Workerman不提供onConnect回调,仅支持onMessage和onError;UdpConnection无连接状态,不可用getRemoteAddress绑定会话;模拟连接需业务层自行实现心跳、缓存与超时清理。

UDP协议本身不建立连接,所以Workerman没有onConnect
UDP是无连接协议,客户端发包即走,服务端收包即处理,中间没有三次握手、没有连接状态维护,自然也就不存在“连接建立”这一事件。Workerman的onConnect只对TCP、WebSocket、HTTP等有连接生命周期的协议有效,UDP Worker压根不会触发它。
你如果在UDP Worker里写了$worker->onConnect回调,代码不会报错,但永远执行不到——这不是Bug,是协议特性决定的。
- UDP Worker只提供
onMessage(收到UDP数据包时触发)和onError(底层socket错误时触发) -
$connection参数在UDP中不是真正的“连接对象”,而是UdpConnection实例,它没有send以外的连接管理方法(比如close无意义,isConnected始终返回false) - 别试图在UDP里用
$connection->getRemoteAddress()做连接绑定或会话跟踪——每次收包的源地址都可能不同,且无法保证下一次还是同一个IP+端口
想实现类似“连接”的语义?得自己加逻辑
有些场景(比如设备心跳注册、客户端身份识别)需要模拟“连接”行为,但必须由业务层补全,Workerman不提供现成机制。
- 在
onMessage里解析包头,提取设备ID或token,查表判断是否为新客户端,再写入内存/Redis缓存 - 用
microtime(true)记录最后活跃时间,配合定时器清理超时条目(不能依赖onClose,因为UDP根本没有这个事件) - 避免把UDP当TCP用:比如反复发同一份“登录请求”并等待响应——UDP丢包不可控,重传、确认、有序交付都得自己实现
误用TCP思维写UDP,最容易踩的三个坑
很多人从TCP转过来写UDP,下意识套用连接模型,结果调试半天发现逻辑不通。
- 在
onMessage里调用$connection->send()后立刻unset($connection)——没用,$connection不是资源句柄,删了也不释放端口或影响后续收包 - 以为
onMessage里的$connection能跨包保持状态(比如存临时变量),但实际上每次回调都是全新上下文;真要共享状态,得用全局数组、静态属性或Redis - 用
telnet测试UDP服务——telnet是TCP工具,根本连不上UDP端口;该用nc -u 服务器IP 端口或echo "test" | nc -u 服务器IP 端口
onConnect,不是功能缺失,而是拒绝掩盖协议本质。真正要用好它,得先放弃“连接已建立”这种确定性假设。

















