延續之前的文章,本文改用SocketIoClient程式庫以及ESP8266控制板(如:Wemos D1 mini或NodeMCU),當ESP8266和Node.js的socket.io建立連線之後,將每隔5秒發送一個事件訊息詢問Node.js目前的時間,Node.js將在收到訊息之後回覆一個事件訊息給ESP8266。
安裝程式庫
本文的範例程式仰賴兩個程式庫,首先安裝Markus Sattler開發的“WebSockets”程式庫:
- 在Arduino IDE中選擇「草稿碼→匯入程式庫→管理程式庫」,在「程式庫管理員」中搜尋“WebSockets”。
- 搜尋“SocketIoClient”並安裝它:
SocketIoClient類別的方法
SocketIoClient程式庫的類別物件具有下列方法,底下的範例假設此物件命名成socket。
begin(主機[, 埠號, 路徑])
連線到socket.io伺服器。「主機」參數是伺服器的網址或IP位址、「埠號」預設為80或443(SSL加密)、「路徑」預設為“/socket.io/?transport=websocket”。語法範例:
socket.begin("192.168.0.111", 5438);
beginSSL (主機[, 埠號, 路徑, 憑證指紋])
採SSL加密連線到socket.io伺服器。憑證指紋(fingerprint)是SSL加密連線憑證的唯一識別值,範例:
socket.beginSSL("my.socket-io.server", 443, "/socket.io/?transport=websocket", "26 96 1C 2A 51 07 FD 15 80 96 93 AE F7 32 CE B9 0D 01 55 C4");
disconnect()
終止連線
emit(事件, 訊息本體)
發送事件訊息給伺服器。「事件」是發送的事件名稱、「訊息本體(payload)」是隨著事件傳送的資料字串。範例:
socket.emit("hello", "\"是在哈囉?\""); // 傳遞普通字串 socket.emit("jsonObj", "{\"foo\":\"bar\"}"); // 傳遞JSON格式字串
loop()
處理socket連線,這個指令要放在Arduino程式的loop()函式裡面。
on(事件, 回呼函式)
將函式綁定到事件。「回呼函式」將在指定「事件」發生時被呼叫,此函式必須包含接收「訊息本體」(字串)及「長度」(數字)兩個參數。底下範例將在收到“hide”事件時,執行“myCallback”函式,其中的size_t類型在Arduino中通常寫成unsigned int。
void myCallback(const char * payload, size_t length) { // 當“hide”事件發生時,執行這裡的程式。 } socket.on("hide", myCallback);
此程式庫具有兩個預設事件名稱:
- connect:連線;當用戶端連結到伺服器時觸發。
- disconnect:斷線;當用戶端中斷與伺服器的連線時觸發。
remove(事件)
移除之前榜定的事件,例如:
socket.remove("hide"); // 移除“hide”事件
setAuthorization(使用者名稱, 密碼)
設置HTTP基本身份驗證用戶名稱和密碼。
與Node.js的socket.io連線通訊的範例程式
Node.js伺服端程式沿用「建立Arduino的Socket即時通訊程式(二)」,ESP8266控制板的程式如下:
#include <ESP8266WiFi.h> #include <SocketIoClient.h> const char* ssid = "Wi-Fi網路名稱"; const char* pwd = "網路密碼"; const char* HOST = "192.168.0.111"; // 請改成你的電腦IP位址 const int PORT = 5438; // 請改成你的Node.js設定的埠號 unsigned long previousMillis = 0; long interval = 5000; // 間隔時間,5秒。 SocketIoClient socket; void setup() { Serial.begin(115200); WiFi.begin(ssid, pwd); // 連接Wi-Fi無線網路 Serial.println(); while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(500); } // 連線到伺服器時,顯示“Connected to server.”。 socket.on("connect", [](const char * payload, size_t len) { Serial.println("Connected to server."); }); // 收到“atime”事件時,顯示收到的資料。 socket.on("atime", [](const char * payload, size_t len) { Serial.printf("got message: %s\n", payload); }); socket.begin(HOST, PORT); // 連線到Node.js的伺服器 } void loop() { socket.loop(); unsigned long currentMillis = millis(); // 每隔5秒送出“atime”事件, // 以及 {"msg":"Time please?"} 資料。 if (currentMillis - previousMillis > interval) { previousMillis = currentMillis; socket.emit("atime", "{\"msg\":\"Time please?\"}"); } }
請先執行Node.js程式,再上傳ESP8266控制板的程式並開啟序列埠監控視窗,能見到如下的通訊結果:
請問有什麼方法可以做到符合商用的加密方法在esp8226上?
請參考這個ESP8266 IoT框架。
thanks,
jeffrey