为什么硬件设备发送数据后Workerman没有触发onMessage回调?

秋静吖_8045

秋静吖_8045

2026-05-22

459人浏览

原创

onmessage不触发,先确认连接是否真正建立成功;检查netstat监听状态、tcp三次握手是否完成、心跳是否被硬件忽略;注意硬件发的是裸字节流,需自定义协议分包,避免阻塞操作导致数据积压。

为什么硬件设备发送数据后workerman没有触发onmessage回调?

onMessage不触发,先看连接是否真建立成功

Workerman的onMessage只在连接已就绪、且有完整数据到达时才触发。如果硬件设备(比如PLC、传感器)发了数据但onMessage完全没反应,大概率不是解析问题,而是连接根本没建稳。

常见错误现象:客户端日志显示“已连接”,但onConnect没执行;或者onConnect执行了,onMessage始终沉默。

  • 用netstat -anp | grep :端口号确认服务端监听正常,且硬件IP确实在ESTABLISHED状态
  • 检查硬件设备是否真的完成了TCP三次握手——有些嵌入式设备发完SYN就卡住,或仅单向发包不收ACK
  • Workerman默认启用心跳检测,若硬件不响应ping帧(如ping_interval超时),连接会被主动断开,onClose会触发,但你可能没监听它

硬件发的是裸字节流,不是HTTP,别期待自动分包

PLC、串口转网关、工控模块等设备几乎都走原始TCP,不带HTTP头、不分chunk、不设Content-Length。Workerman收到的就是一坨连续字节,onMessage回调里的$data就是原始二进制或乱码字符串——这不是bug,是协议本该如此。

常见错误现象:echo $data看到一堆不可见字符、长度忽长忽短、偶尔截断、甚至空字符串。

Flova
Flova

Flova是一款AI文本写作工具,全球首个一体化 AI 视频创作平台。

下载
  • 必须自己定义应用层协议:比如以\n、\r\n或固定长度(如16字节/帧)为边界
  • 不要依赖$_POST或$request->post()——这些只对HTTP有效,TCP下压根不存在
  • 开启$connection->protocol = 'text'或自定义协议类,让Workerman帮你按行或按帧拆包(否则所有数据会攒在缓冲区,直到超时或缓冲满才吐一次)

发送太快,接收被系统缓冲区“吞掉”了

硬件设备常以毫秒级间隔连续发多条指令(比如每10ms读一次寄存器),而Workerman的事件循环若被阻塞(如定时器里密集send()、或onMessage里做了耗时同步操作),会导致onMessage回调迟迟得不到调度,数据全堆在内核recv缓冲区里不动。

典型表现:Wireshark能看到设备确实在发包,但PHP里onMessage几秒后才突然一次性收到十几条拼在一起的数据。

  • 避免在onMessage里做sleep、file_get_contents、curl等阻塞操作
  • 如果必须轮询硬件,改用Worker::signal或Timer::add异步调度,别卡主线程
  • 紧急补救:在onMessage处理完后手动调用$connection->baseRead($connection->getSocket()),强制触发下一轮读取(参考PLC通信真实案例)

编码/字节序/校验字段导致数据被静默丢弃

很多工业协议要求首字节为命令码、末尾含CRC16校验、或整数字段用大端序(Big-Endian)。Workerman不会帮你校验或转换——它只负责把收到的字节原样交给onMessage。如果你的解析逻辑一上来就unpack('V', $data)却忘了设备发的是N(大端ulong),结果就是解出0或负数,后续直接跳过处理。

常见错误现象:onMessage能触发,但你的业务逻辑总判断“非法帧”然后return,看起来像没收到。

  • 先用bin2hex($data)打印原始十六进制,对照设备手册确认帧结构是否匹配
  • 检查是否漏了粘包处理:两条帧连在一起发过来,你按单帧解析就会失败
  • 确认$connection->transport是tcp而非ssl——某些硬件不支持TLS握手,强行配SSL会导致连接后立即断开,onMessage自然不会触发
真正难的不是写onMessage函数,而是确认那几字节数据从硬件引脚出发,经过网线、交换机、Linux协议栈、Workerman事件循环,最后稳稳落在$data变量里——中间任何一环掉链子,它都不会提醒你。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

9944

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

5921

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2075

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3708

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4394

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3451

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

4917

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3842

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11802

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Webman中文手册
Webman中文手册

共0课时 | 0人学习

Workerman官方手册
Workerman官方手册

共0课时 | 0人学习

ThinkPHP5.1完全开发手册
ThinkPHP5.1完全开发手册

共0课时 | 0人学习