基于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()函数是行不通的,必须基于第二种方式曲线实现硬件通信。

首先在Command中添加内部端口的监听,注意onReceive事件被自定义的InnerHandler接收(不知所云者请复习上一篇以及Swoole的文档)。
一定记得在iptables中把你的内部监听端口打开!!
 

在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的,有兴趣的朋友可以耐心等待代码和文章。

posted @ 2016-06-30 01:19  保安保安  阅读(8541)  评论(12编辑  收藏  举报