esp32 micropython web服务器_ESP32 Arduino教程:Websocket server(服务器)
本文主要介紹如何使用Arduino內(nèi)核作為編程架構(gòu)在ESP32(上創(chuàng)建Websocket server(服務(wù)器)。所創(chuàng)建的Websocket server(服務(wù)器)將作為回發(fā)服務(wù)器使用,也就是說(shuō)它會(huì)把接收自客戶端的數(shù)據(jù)回發(fā)給客戶端。
為了對(duì)服務(wù)器進(jìn)行測(cè)試,我們將使用Python開(kāi)發(fā)一個(gè)非常簡(jiǎn)單的客戶端。即便是對(duì)從沒(méi)用過(guò)Python的人來(lái)說(shuō),這也是一種非常簡(jiǎn)單(也非常強(qiáng)大)的程序設(shè)計(jì)語(yǔ)言,因此以下代碼肯定不難理解。
當(dāng)然,如果你仍然不習(xí)慣使用Python,你也可以參考上一篇帖子使用另一個(gè)ESP32開(kāi)發(fā)板上運(yùn)行的ESP 32 Websocket客戶端或者使用其他編程語(yǔ)言開(kāi)發(fā)的Websocket API對(duì)代碼進(jìn)行測(cè)試。
在ESP32上需要安裝一個(gè)Websockets庫(kù),這樣就不需要從頭編寫(xiě)底層代碼了。我們將使用這個(gè)基于WiFiServer的庫(kù)(來(lái)創(chuàng)建一個(gè)TCP服務(wù)器(這也是Arduino內(nèi)核的常見(jiàn)做法)。
需要注意的是,我在撰寫(xiě)本文時(shí),上面提到的Websockets庫(kù)尚未得到ESP32的官方支持(官方支持僅限ESP8266)。盡管如此,經(jīng)過(guò)略微修改之后,仍可在ESP32上使用這個(gè)庫(kù)。
在此前的這篇教程中:ESP32 Arduino教程:Websocket客戶端(已經(jīng)詳細(xì)介紹了庫(kù)的安裝過(guò)程。請(qǐng)參閱此篇教程,因?yàn)樵谑褂脦?kù)之前有幾點(diǎn)技巧需要考慮。
下面所示的Arduino代碼就是對(duì)庫(kù)的例程進(jìn)行修改所得到的,可以成功用在ESP32上。
我們還需要在Python上安裝一個(gè)Websockets模塊,同樣可以使我們免于處理Websockets的底層實(shí)現(xiàn)。
我們將使用一個(gè)叫做websocket-client的Python模塊(。幸運(yùn)的是,Python自帶了一個(gè)叫做pip的軟件包安裝程序(,可以大大簡(jiǎn)化模塊的安裝過(guò)程。
因此,要安裝上文提到的庫(kù),我們只需要在Windows命令行執(zhí)行以下命令即可:
請(qǐng)注意,根據(jù)您所使用的Python具體版本的不同,在發(fā)送命令之前可能需要導(dǎo)航到pip所在的文件夾。
首先,導(dǎo)入剛剛安裝的websocket client模塊。此外,還需要導(dǎo)入time模塊,以便在程序中加入延時(shí)。
接下來(lái),調(diào)用WebSocket對(duì)象的connect方法(使用服務(wù)器地址作為其輸入?yún)?shù))。
請(qǐng)注意,由于這是一個(gè)websocket連接,我們需要將目標(biāo)設(shè)為“ws://{serverIP}/“,其中服務(wù)器IP是ESP32連接到WiFi網(wǎng)絡(luò)時(shí)所分配的地址。
代碼中使用的是我的ESP32開(kāi)發(fā)板的IP地址,在連接到我的家庭網(wǎng)絡(luò)時(shí)我已經(jīng)知道了具體的IP地址。但是,如果你還不知道你的IP地址,那么我們會(huì)在Arduino代碼中將其值打印出來(lái)。
上述函數(shù)調(diào)用之后,我們就應(yīng)該成功連接到了服務(wù)器上。請(qǐng)注意,為簡(jiǎn)便起見(jiàn),我在代碼中沒(méi)有進(jìn)行任何錯(cuò)誤處理,但是在實(shí)際應(yīng)用中對(duì)可能出現(xiàn)的錯(cuò)誤進(jìn)行處理非常重要。
接下來(lái),為了向服務(wù)器發(fā)送數(shù)據(jù),我們只需調(diào)用WebSocket對(duì)象的send方法即可(將包含數(shù)據(jù)內(nèi)容的字符串作為輸入?yún)?shù))。
為了從服務(wù)器接收數(shù)據(jù),我們可以調(diào)用WebSocket對(duì)象的recv方法。該方法會(huì)從服務(wù)器返回可用的數(shù)據(jù),我們應(yīng)該把這些數(shù)據(jù)保存到變量中。
Python Websocket client的完整源代碼如下所示。請(qǐng)注意,代碼中使用循環(huán)發(fā)送和接收請(qǐng)求,并將從服務(wù)器接受到的數(shù)據(jù)打印出來(lái),以確認(rèn)服務(wù)器真的會(huì)將接受到的內(nèi)容進(jìn)行回發(fā)。
你可以修改nrOfMessages變量和sleep時(shí)間,以測(cè)試服務(wù)器在面對(duì)更多請(qǐng)求和更短間隔時(shí)的靈活性。
然后,我們需要一個(gè)WiFiServer類的對(duì)象,所以我們將創(chuàng)建一個(gè)TCP服務(wù)器并使其監(jiān)聽(tīng)接受到的請(qǐng)求。websocket server(服務(wù)器)也將在這個(gè)服務(wù)器之上構(gòu)造。
這個(gè)類的構(gòu)造函數(shù)有一個(gè)可選參數(shù),可指定服務(wù)器將要監(jiān)聽(tīng)的端口號(hào)。盡管其默認(rèn)值就是80,但是我們?nèi)詫@式地傳遞該輸入?yún)?shù),以說(shuō)明其用途。
我們還需要一個(gè)WebSocketServer類的對(duì)象(,它負(fù)責(zé)提供從客戶端接收請(qǐng)求以及對(duì)數(shù)據(jù)交換進(jìn)行處理時(shí)所需要的方法。
在全局變量聲明的最后,我們需要將WiFi網(wǎng)絡(luò)名稱(ssid)及其密碼保存起來(lái),以便稍后聯(lián)網(wǎng)時(shí)使用。
然后,將ESP32連接到WiFi網(wǎng)絡(luò),并將分配給它的本地IP地址打印出來(lái)。這個(gè)IP地址正是在前文所述Python代碼中使用的地址。
有關(guān)如何將ESP32連接到WiFi網(wǎng)絡(luò)的詳細(xì)說(shuō)明,請(qǐng)參閱此前的這篇帖子:ESP32 MicroPython教程:連接Wi-Fi網(wǎng)絡(luò)(。
在setup函數(shù)的最后,通過(guò)調(diào)用WiFiServer對(duì)象的begin方法對(duì)TCP服務(wù)器進(jìn)行初始化。該方法沒(méi)有輸入?yún)?shù),返回值為空。
首先,通過(guò)調(diào)用WiFiServer對(duì)象的available方法對(duì)客戶端連接進(jìn)行監(jiān)聽(tīng)。該方法會(huì)返回一個(gè)WiFiClient類(的對(duì)象。
請(qǐng)注意,我們目前仍然處于TCP客戶端層次,尚未涉及websocket客戶端。
接下來(lái),為了確認(rèn)TCP客戶端是否已連接,需要在先前返回的WiFiClient對(duì)象上調(diào)用connected方法,如果客戶端已連接,則該方法返回值為true,否則返回值為false。
我們還需要調(diào)用WebSocketServer對(duì)象(該對(duì)象是我們?cè)诖a一開(kāi)始所聲明的一個(gè)全局變量)的handshake方法,其輸入?yún)?shù)是我們的WiFiClient對(duì)象,這個(gè)handshake方法(負(fù)責(zé)在底層完成協(xié)議握手。
Handshake方法會(huì)返回一個(gè)Boolean(布爾)值,表示握手是否成功,在進(jìn)一步與客戶端進(jìn)行實(shí)際通信之前,應(yīng)該對(duì)這個(gè)返回值進(jìn)行驗(yàn)證(以確保握手成功)。
鑒于我們將使用非常簡(jiǎn)單的websocket回發(fā)服務(wù)器,因此只需要一個(gè)數(shù)據(jù)緩沖區(qū),用于存放首次接收的客戶端數(shù)據(jù)。在接下來(lái)的代碼中,所有方法使用的參數(shù)都是字符串類型,與我們的緩沖區(qū)數(shù)據(jù)類型一致。
客戶端隨時(shí)可能斷開(kāi),因?yàn)槲覀儗⑹褂靡粋€(gè)while循環(huán),只要客戶端仍處于連接狀態(tài),這個(gè)循環(huán)就會(huì)持續(xù)運(yùn)行。
在循環(huán)的每次迭代之間,需要加入一小段延時(shí)。這一點(diǎn)非常重要,如果沒(méi)有延時(shí),那么在收到最開(kāi)始的幾個(gè)字節(jié)之后,代碼將會(huì)停止從客戶端接收數(shù)據(jù)。
在循環(huán)內(nèi),我們通過(guò)webSocketServer對(duì)象的getData方法(接收數(shù)據(jù)。該方法不需要輸入?yún)?shù),返回String(字符串)輸出,我們會(huì)把這個(gè)返回值賦值給之前定義的數(shù)據(jù)緩沖區(qū)。
通過(guò)調(diào)用WebSocketServer對(duì)象的sendData方法(可以將數(shù)據(jù)發(fā)送給客戶端。該方法接收String(字符串)輸入(該字符串的內(nèi)容就是要發(fā)送給客戶端的數(shù)據(jù)),返回值為空。
客戶端有可能不發(fā)送任何數(shù)據(jù),所以我們要先確認(rèn)數(shù)據(jù)緩沖區(qū)的長(zhǎng)度,并通過(guò)條件判斷確定是否執(zhí)行上述方法調(diào)用。數(shù)據(jù)緩沖區(qū)的長(zhǎng)度應(yīng)該大于0,這樣我們才會(huì)把數(shù)據(jù)回發(fā)給客戶端。
完整的Arduino循環(huán)函數(shù)如下所示。請(qǐng)注意,我們?cè)黾恿水?dāng)客戶端從服務(wù)器斷開(kāi)時(shí)打印相關(guān)消息的額外代碼,位于循環(huán)內(nèi)判斷客戶端是否連接的相關(guān)代碼之后。
最終的Arduino代碼如下所示。您可以直接復(fù)制粘貼到自己的Arduino環(huán)境內(nèi)。不要忘了在全局變量中改為你自己的WiFi網(wǎng)絡(luò)認(rèn)證信息。
使用你的Arduino IDE對(duì)代碼進(jìn)行編譯并上傳到ESP32開(kāi)發(fā)板,即可對(duì)代碼進(jìn)行測(cè)試。然后,打開(kāi)serial monitor(使用Serial.Begin函數(shù)中定義的波特率)。
連接到WiFi網(wǎng)絡(luò)時(shí),控制臺(tái)會(huì)打印出ESP32的本地IP。Python程序中執(zhí)行connect方法時(shí)使用的就是這個(gè)IP。
在Python程序中寫(xiě)入正確的IP并且連接ESP32之后,運(yùn)行Python程序。發(fā)送到ESP32的消息全部被回發(fā)并打印到了Python控制臺(tái),如圖1所示。
在所有消息發(fā)送完之后,Python客戶端會(huì)從服務(wù)器斷開(kāi)。Arduino循環(huán)會(huì)檢測(cè)到客戶端已斷開(kāi),因此在控制臺(tái)上會(huì)打印出一條消息,說(shuō)明客戶端已經(jīng)斷開(kāi),如圖3所示。
注:本文作者是Nuno Santos,他是一位和藹可親的電子和計(jì)算機(jī)工程師,住在葡萄牙里斯本 (Lisbon)。
本文來(lái)自: 老鐵博客,轉(zhuǎn)載請(qǐng)保留出處!歡迎發(fā)表您的評(píng)論
相關(guān)標(biāo)簽:web程序
總結(jié)
以上是生活随笔為你收集整理的esp32 micropython web服务器_ESP32 Arduino教程:Websocket server(服务器)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 平滑线反锯齿工具_PS大神常用选框类工具
- 下一篇: ps抠头发插件_PS顶级抠图插件Topa