使用MicroPython開發ESP32(06):WebServer功能實現簡單說明

目的

WebServer是非常常用的一個功能,在設備上使用該功能用戶就可以不依賴app直接通過瀏覽器訪問和操作設備。另外即使是用app的,對於app開發來說直接訪問webapi也比處理tcp/udp要方便些。本文將簡單介紹使用基於TCP的socket編程來實現WebServer功能。

WebServer基礎說明

WebServer主要是用作對客戶端發出的基於HTTP協議的請求進行響應(比如用戶通過瀏覽器輸入某個網址進行訪問的時候就會向該地址發送請求頭)。請求頭示例如下:

GET / HTTP/1.1
Host: www.baidu.com
Connection: close
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0) Gecko/20100101 Firefox/6.0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8

上面的一段字符串就是一個請求頭(注意最後的空行),該請求請求訪問百度首頁,百度的服務器收到該請求後就返回 響應頭所請求的內容
上面的請求頭其實就是個字符串,字符串中包含特定內容和格式(這就是HTTP協議所規定的),這個字符串通過TCP方式進行傳輸,所以我們可以用TCP方式的socket編程實現WebServer功能。

WebServer使用演示

基礎實現演示

下面是個通過TCP方式的socket編程實現WebServer功能的簡單演示:

import network
import usocket as socket  # 引用socket模塊

# 響應頭
responseHeaders = b'''
HTTP/1.1 200 OK
Content-Type: text/html
Connection: close

'''
# 響應頭網頁正文內容
content = b'''
Hello World!
'''

ap = network.WLAN(network.AP_IF)
ap.config(essid='lalala', authmode=4, password='12345678')
ap.active(True)  # 開啓無線熱點


def main():
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # (重要)設置端口釋放後立即就可以被再次使用
    s.bind(socket.getaddrinfo("0.0.0.0", 80)[0][-1])  # 綁定地址
    s.listen(5)  # 開啓監聽(最大連接數5)

    print('接入熱點後可從瀏覽器訪問下面地址:')
    print(ap.ifconfig()[0])
    print('')

    while True:  # mian()函數中進行死循環,在這裏保持監聽瀏覽器請求與對應處理
        client_sock, client_addr = s.accept()  # 接收來自客戶端的請求與客戶端地址
        print('Client address:', client_addr)

        while True:
            h = client_sock.readline() # 按行讀取來自客戶端的請求內容
            print(h.decode('utf8'), end='')
            if h == b'' or h == b'\r\n':  # 當讀取到空行的時候表示接收到一個完整的請求頭
                break

        client_sock.write(responseHeaders) # 向客戶端發送響應頭
        client_sock.write(content) # 向客戶端發送網頁內容
        client_sock.close()


main()  # 運行main()函數

在這裏插入圖片描述
上面例子中我開啓了TCP監聽,然後通過瀏覽器訪問時就可以收到來自瀏覽器的請求,代碼中逐行讀取請求內容,在讀取到空行後當作請求完整,然後向瀏覽器發送了響應頭和網頁內容。
在上面例子中沒有檢查請求的內容,實際使用中需要解析請求內容,在根據請求的內容進行響應(比如通過瀏覽器請求控制某個IO口來驅動LED等等功能)。

通過瀏覽器控制設備

WebServer最實用的功能就是通過瀏覽器獲取或控制電路的狀態了,下面例子進行了簡單的演示:

import network
from machine import Pin 
import usocket as socket  # 引用socket模塊

ap = network.WLAN(network.AP_IF)
ap.config(essid='lalala', authmode=4, password='12345678')
ap.active(True)  # 開啓無線熱點

led = Pin(13, Pin.OUT, value=0) # 初始化LED管腳,低電平點亮

def main():
    s = socket.socket()
    s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # (重要)設置端口釋放後立即就可以被再次使用
    s.bind(socket.getaddrinfo("0.0.0.0", 80)[0][-1])  # 綁定地址
    s.listen(5)  # 開啓監聽(最大連接數5)

    print('接入熱點後可從瀏覽器訪問下面地址:')
    print(ap.ifconfig()[0])
    print('')

    while True:  # mian()函數中進行死循環,在這裏保持監聽瀏覽器請求與對應處理
        client_sock, client_addr = s.accept()  # 接收來自客戶端的請求與客戶端地址

        q = ''
        while True:
            h = client_sock.readline()  # 按行讀取來自客戶端的請求內容
            q += h.decode('utf8')
            if h == b'' or h == b'\r\n':  # 當讀取到空行的時候表示接收到一個完整的請求頭
                break

        if q.startswith('GET / HTTP/1.1'): # 從瀏覽器訪問 /
            client_sock.write('led is on' if(not led.value()) else 'led is off')  # 向客戶端發送內容
        elif q.startswith('GET /on HTTP/1.1'): # 從瀏覽器訪問 /on
            led.off() # 低電平點亮led
            client_sock.write('led turn on')  # 向客戶端發送內容
        elif q.startswith('GET /off HTTP/1.1'): # 從瀏覽器訪問 /off
            led.on() # 高電平關閉led
            client_sock.write('led turn off')  # 向客戶端發送內容
        else:
            client_sock.write('not found')  # 向客戶端發送內容

        client_sock.close()


main()  # 運行main()函數

在這裏插入圖片描述
上面例子中通過瀏覽器訪問不同鏈接,WebServer檢索請求頭內容分別給出不同應答。

更多內容可以參考我別的博文:
《從零開始的ESP8266探索(06)-使用Server功能搭建Web Server》

第三方WebServer庫介紹

實際使用中如果用上面的方式處理,如果遇到大型的項目就顯得麻煩了,這時候可以嘗試使用人家寫好的WebServer庫,這裏介紹一些:

  • MicroWebSrv
    這個庫注意用於MicroPython,總共就三個文件,分別提供了WebServer基本功能、WebSocket、模板支持。

    MicroWebSrv is a micro HTTP Web server that supports WebSockets, html/python language templating and routing handlers, for MicroPython (principally used on ESP32 and Pycom modules. Now supports all variants of Pyboard D-series from the makers of Micropython)

    項目地址:https://github.com/jczic/MicroWebSrv

  • MicroWebSrv2
    這個庫功能更加全面,性能上也更好,不過庫的大小和內存佔用也更加高了,基本上不帶外部SPI RAM的ESP32模塊都別想好好跑。這個庫不僅持MicroPython,還支持標準的CPython。

    MicroWebSrv2 is the new powerful embedded Web Server for MicroPython and CPython that supports route handlers, modules like WebSockets or PyhtmlTemplate and a lot of simultaneous requests (in thousands!).


    Fully asynchronous, its connections and memory management are very optimized and truly fast.


    Mostly used on Pycom WiPy, ESP32, STM32 on Pyboard, … Robust and efficient!

    項目地址:https://github.com/jczic/MicroWebSrv2

總結

WebServer是一個常用的功能,MicroPython上想要用也不麻煩,更多內容除了可以參考上面第三方的庫,也可以參考官方的例程。MicroPython官方的WebServer例程可以在下面鏈接中找到:
https://github.com/micropython/micropython/tree/master/examples/network

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章