基于Laravel+Swoole开发智能家居后端
基于Laravel+Swoole开发智能家居后端
在上一篇<Laravel如何优雅的使用Swoole>中我已经大概谈到了Laravel结合Swoole的用法。
今天,我参与的智能家居项目基本上已经结束了Web服务器及android端的开发(熬了个通宵突击把剩下的做了,好累), 趁热来聊聊基于Laravel+Swoole开发智能家居后端的关键技术点。
16进制ASCII码协议的解析
硬件我不谈,我只需要关心数据解析。如何基于Swoole如果在php中解析16进制的ascii码,这种文章还比较少呢。但核心的部分还是可以整理出来的,关键用到的就是chr()、hexdec()、bin2hex()这3个函数,网上还提到了用pack()、unpack(),因为前面3个函数以及很好的解决了问题,所以就没有继续深入。我建议在这里Php Manual官网先熟悉下这几个函数。
chr()函数从不同的 ASCII 值返回字符,hexdec() 函数把十六进制转换为十进制。通常结合这两个函数把16进制字符串转换为ASCII字符串,理解起来有点绕。
例如: echo chr(hexdec('fe'));//输出的就是下位机能认识的16进制的FE,大小写不敏感 bin2hex()函数把 ASCII 字符的字符串转换为十六进制值,用于从Swoole中读取数据的转换。
例如:$buffer = str_split(bin2hex($data), 2);//$data是Swoole中OnReceive事件传递的值
在解析协议时,上例中的$buffer数组中,存放了协议的每一位。那么怎么解析呢?最快最懒的方法就是根据硬件研发的协议一位一位的去读取数据,例如头是第一位,那么就是$buffer[0];如果连着好几位组合起来是数据,就写个小函数拼。
是不是太弱鸡了点(.NET和JAVA有很丰富的byte[]转整形和字符串的方法集)?如果你需要,可以自己写个转换工具类出来(我暂时用不上就没整理)。
在下位机通信中还有一个很重要的技术点就是XOR校验,我是从stackoverflow找到的源码,直接贴地址。
16进制ASCII码协议的创建
不废话,直接上代码:
对Laravel使用者,在这部分我强烈建议好好复习一下Laravel提供的快速数组函数辅助方法。
与硬件的曲线通信
基于Swoole接收数据在上一篇中已经详细介绍不再累述,这里主要说说向硬件发送数据的问题。上一篇中,我提到了2种方法,一种是利用fsockopen()函数;一种是内部端口监听。这里还和搞硬件的大神闹了个笑话,脸红啊..对基于TCP/IP协议的通信,因为端口一直被接收监听占用,所以用fsockopen()或者socket_write()函数是行不通的,必须基于第二种方式曲线实现硬件通信。


在Innerhandler中,若接收到需要发送到硬件的命令(就是上一节说的数据),从缓存里面提取该硬件的连接实体,然后发送数据(不知所云请参考Swoole文档)。
这里比较曲线的情况就是在这个缓存,这个缓存是在需要发送数据的时候设定的,那么怎么知道硬件的连接实体是什么?当然是保持一个KV结构的数据啦:)
整个曲线的通信过程就是:当需要向硬件发送数据的时候,首先将数据发送到这个内部监听端口来,然后再从这里发送到硬件去。
怎么向内部监听端口发送数据呢?用fsockopen()或者socket_write()都是完全没问题的,这里的代码就请自行搜索,权当练习,不要太懒了。
Event大有裨益
这个要用过了才知道有多方便,来这里先好好复习一下。实现过程请自行感受,我就只说说我哪里用到了Event:
1.基于JPUSH推送消息
2.向内部监听发送数据
另外只补充一点,想利用Event通过Swoole发送数据的路是行不通的。
优雅的快速测试
由于PHP是弱类型,因此理解起来比较费解。接收数据和向硬件发送数据的数据类型是不一样的。用bin2hex()得到的是形如"11 00 00 FE"的字符串,用chr(hexdec())得到的是16进制的ASCII码,如果echo输出的话,会是乱码。那么如何测试(看到)自己生成的16进制ASCII码数据是否正确呢?1种是找一个TCP/IP工具发送过去,这种麻烦了点,我推荐用fiddler监听。
你可以快速方便的用一个web页面输出你的ASCII码,在fiddler的HexView中,就可以看到原汁原味你发送的16进制数据了。另外,由于Swoole的监听类是CLI运行,因此我也非常推荐多写一点echo打印一下状态,在phpstorm的SSH客户端里可以快速的了解目前的情况,就像android-studio的Loger一样。
echo Carbon::now() . '/Device Numbers:' . $devNum . PHP_EOL;//老司机劝你多写点,最好packagist找个轮子或者自己写个Logger库
鲁棒性探讨,可以搞得非常复杂
算吐个槽吧,前年用.NET做下位机数据处理鲁棒性的时候真是如坐针毡啊。搞下位机通信果然还是c++最合适啊,以下问题在这里还需要后期逐步完善呢:
1.如果硬件发送的数据不是一个包发完而是分批发怎么办?
2.看门狗是一定要写的,对吧?
3.与硬件通信的response处理要做吧?
4.TimeOut怎么办?
....
啊啊啊啊啊....
喜欢Android的有福了
预告下,基于学习的目的,最近正在仿鲜城、enjoy、半糖这3个很有代表性的电商APP首页UI(是逆向着看smali和提取res在仿哟)。
鲜城的android端已经做的有模有样了,这次是逼着自己android、ios都给仿出来,没老司机带就自己想办法提高。
先做android的,有兴趣的朋友可以耐心等待代码和文章。
基于Laravel+Swoole开发智能家居后端的更多相关文章
- 基于能量收集的智能家居-2013国家级大学生创业实践项目申报_商业计划书_V0.2
SmartHome项目商业计划 基于能量收集的 免电池无线智能家居系统 IA-SmartHome团队 2012.12 l 基于无线的智能家居解决方案,节省施工成本: l 基于能 ...
- Android开发—智能家居系列】(二):用手机对WIFI模块进行配置
在实际开发中,我开发的这款APP是用来连接温控器,并对温控器进行控制的.有图为证,哈哈. 上一篇文章[Android开发—智能家居系列](一):智能家居原理的文末总结中写到: 手机APP控制智能温控器 ...
- 【Android开发—智能家居系列】(一):智能家居原理
来到JCZB公司的第二天,就接到了开发类似于小米智能家庭APP的任务.组长让我在手机上安装上此款APP,给了我个小米智能插座,就让我开始了解需求.这便开启了我的智能家居旅程.说实话,我也真是out的无 ...
- 【Android开发—智能家居系列】(四):UDP通信发送指令
思路回顾 [1]手机连接WIFI模块 [2]UDP通信对WIFI模块发送指令,以和WIFI模块保持连接状态 [3]UDP通信对WIFI模块发送指令,让其搜索可用的无线网,返回WIFI列表 [4]发送指 ...
- 【Android开发—智能家居系列】(三):手机连接WIFI模块
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[+] 概述 实现连接WIFI的功能会用到一个工具类,源码可以点击链接下载.网上这些类似的工具类里的代码差不多是一样的.连接无线网主要有 ...
- 智能家居APP开发
智能家居APP开发 APP开发技术qq交流群:347072638 前言,随着智能硬件设备的流行,智能家居開始红火,智能家居就是家用电器的智能化.包含智能锁,灯,空调,灯,音箱等等,移动设备通过WIFI ...
- 智能家居中的物联网网关的可信计算平台模块(TPM)设计
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/BlueCloudMatrix/article/details/24184461 摘要: 随着智能家居 ...
- 硬纪元AI峰会前瞻:如何才能做好智能家居?用户体验最重要
用户体验不到位,市场就不能说真的发展起来. 可以明显的感觉到,随着人工智能.物联网等技术的发展和应用,我们的生活正在发生翻天覆地的变化,其中感觉最为明显的就是智能家居. 据前瞻产业研究院的数据统计,我 ...
- 基于 Laravel、Vue.js开发的全新社交系统----ThinkSNS+
什么是ThinkSNS+ ThinkSNS(简称TS)始于2008年,一款全平台综合性社交系统,为国内外大中小企业和创业者提供社会化软件研发及技术解决方案,目前最新版本为ThinkSNS+.新的产品名 ...
随机推荐
- 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个依赖项 解决方法
在webconfig中加入这段话就可以了 <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:as ...
- java学习之 反射
以前学习java只是学习了基本语法操作,各种常用方法的使用,随着慢慢学习,很多大神都觉得要想成为大神,就必须把java的反射给理解透,这样我就带着好奇的心去学习到底反射是什么玩意,所以就上网找资料学习 ...
- Linux中的SWAP交换分区
大多数 Linux 在系统安装时都会提醒并建议你划分一个 SWAP 交换分区,如果你是从 Windows 切换到 Linux 的新用户,兴许对这个 SWAP 会感到十分疑惑. SWAP 交换分区到底是 ...
- android oncreate获取宽高度
gridView = (GridView) getView().findViewById(R.id.gridView_musicbook); gridView.getViewTreeObserver( ...
- 系统进程 zygote(二)—— zygote.rc 脚本
夕阳已在沉沉的淡化,这黄昏的美,有谁能描画?莽莽的天涯,哪里是我的家,哪里是我的家?爱人呀,我这般的想着你,你那里可也有丝毫的牵挂?—— 徐志摩·海边的梦 ilocker:关注 Android 安全( ...
- 解决AutoCAD2010在VS2010上无法命中断点
AutoCAD 2010的二次开发告一段落,现在整理一些开发中遇到的问题. 最早遇到的问题是关于AutoCAD 2010在VS 2010上无法调试.奇怪的是这问题只出现在我同事电脑上,我的电脑一切OK ...
- AWS国际版的Route 53和CloudFront
注册AWS国际版账号后,却发现Route 53和CloudFront功能是无法使用的.于是提交了一个Service Request,得到的答复是这两个功能需要验证后才能激活. 在控制台中点击进入Rou ...
- unix automake 使用,快速生成你的Makefile
使用automake快速生成编译的Makefile 1,确保自己装有的软件automake autoconf 2, 1)执行autoscan 并将生成的configure.scan重命名为config ...
- continue break return的区别
1.continue 语句的作用 终止本次循环的执行,即跳过当前一次循环中continue语句后尚未执行的语句,然后进行下一次循环条件的判断. 2.break 语句的作用 (1)当 ...
- LinuxAsm#Chapter10
Dividing and Conquering Book: Assembly Language step by step Complexity kills programs. Remember to ...