建立Arduino的Socket即時通訊程式(三)

延續之前的文章,本文改用SocketIoClient程式庫以及ESP8266控制板(如:Wemos D1 mini或NodeMCU),當ESP8266和Node.js的socket.io建立連線之後,將每隔5秒發送一個事件訊息詢問Node.js目前的時間,Node.js將在收到訊息之後回覆一個事件訊息給ESP8266。

ESP8266 Socket.io通訊

安裝程式庫

本文的範例程式仰賴兩個程式庫,首先安裝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控制板的程式並開啟序列埠監控視窗,能見到如下的通訊結果:

序列埠監控視窗

Posts created 483

2 thoughts on “建立Arduino的Socket即時通訊程式(三)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top