基於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的,有興趣的朋友可以耐心等待代碼和文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM