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