選單
×
   ❮     
HTML CSS JAVASCRIPT SQL PYTHON JAVA PHP HOW TO W3.CSS C C++ C# BOOTSTRAP REACT MYSQL JQUERY EXCEL XML DJANGO NUMPY PANDAS NODEJS R TYPESCRIPT ANGULAR GIT POSTGRESQL MONGODB ASP AI GO KOTLIN SASS VUE DSA GEN AI SCIPY AWS CYBERSECURITY DATA SCIENCE
     ❯   

Node.js 和 Raspberry Pi - 帶WebSocket的Web伺服器


什麼是WebSocket?

WebSocket 支援即時雙向通訊。

WebSocket 可以與常規HTTP伺服器一起執行。你可以點選網頁瀏覽器中的按鈕,然後啟用Raspberry Pi上的GPIO,從而開啟你家中的燈。所有這些都是即時的,並且通訊是雙向的!

在本章中,我們將設定一個帶WebSocket的Web伺服器。然後建立一個瀏覽器UI來與我們之前關於用按鈕控制LED開關的示例進行互動。


我需要什麼?

本教程需要一臺Raspberry Pi。在我們的示例中,我們使用的是Raspberry Pi 3,但本教程應該適用於大多數版本。

For this you need

Click the links in the list above for descriptions of the different components.

Note: The resistor you need can be different from what we use depending on the type of LED you use. Most small LEDs only need a small resistor, around 200-500 ohms. It is generally not critical what exact value you use, but the smaller the value of the resistor, the brighter the LED will shine.

與我們之前的示例相比,我們唯一需要新增的是設定一個Web伺服器,並安裝socket.io模組。


Raspberry Pi 和 Node.js 的 Web伺服器

遵循本Node.js教程之前的章節,讓我們設定一個可以提供HTML檔案的Web伺服器。

在我們的“nodetest”目錄中,建立一個新目錄,用於存放靜態HTML檔案

pi@w3demopi:~/nodetest $ mkdir public

現在讓我們設定一個Web伺服器。建立一個Node.js檔案,該檔案會開啟請求的檔案並將內容返回給客戶端。如果出現任何錯誤,則丟擲404錯誤。

pi@w3demopi:~/nodetest $ nano webserver.js

webserver.js

var http = require('http').createServer(handler); //需要http伺服器,並用handler()函式建立伺服器
var fs = require('fs'); //需要檔案系統模組

http.listen(8080); //監聽8080埠

function handler (req, res) { //建立伺服器
  fs.readFile(__dirname + '/public/index.html', function(err, data) { //讀取public資料夾中的index.html檔案
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'}); //錯誤時顯示404
      return res.end("404 Not Found");
    }
    res.writeHead(200, {'Content-Type': 'text/html'}); //寫入HTML
    res.write(data); //寫入index.html中的資料
    return res.end();
  });
}

進入“public”資料夾

pi@w3demopi:~/nodetest $ cd public

然後建立一個HTML檔案,index.html

pi@w3demopi:~/nodetest/public $ nano index.html

index.html

<!DOCTYPE html>
<html>
<body>

<h1>控制LED燈</h1>
<input id="light" type="checkbox">LED

</body>
</html>

這個檔案現在還沒有任何功能。目前它只是一個佔位符。讓我們看看Web伺服器是否正常工作

pi@w3demopi:~/nodetest/public $ cd ..
pi@w3demopi:~/nodetest $ node webserver.js

使用 http://[RaspberryPi_IP]:8080/ 在瀏覽器中開啟網站

現在Web伺服器應該已經啟動並執行,我們可以繼續進行WebSocket部分了。


安裝Node.js的socket.io

設定好Web伺服器後,將你的Raspberry Pi系統包更新到最新版本。

Update your system package list

pi@w3demopi:~ $ sudo apt-get update

將所有已安裝的軟體包升級到最新版本

pi@w3demopi:~ $ sudo apt-get dist-upgrade

定期執行此操作可以保持你的Raspberry Pi安裝的最新。

要下載並安裝最新版本的socket.io,請使用以下命令

pi@w3demopi:~ $ npm install socket.io --save


為Web伺服器新增WebSocket

現在我們可以在應用程式中使用WebSocket了。讓我們更新index.html檔案

index.html

<!DOCTYPE html>
<html>
<body>

<h1>控制LED燈</h1>
<p><input type="checkbox" id="light"></p>

<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script> <!-- 包含socket.io客戶端指令碼 -->
<script>
var socket = io(); //載入socket.io-client並連線到提供頁面的主機
window.addEventListener("load", function(){ //頁面載入時
  var lightbox = document.getElementById("light");
  lightbox.addEventListener("change", function() { //新增事件監聽器,用於複選框變化時
    socket.emit("light", Number(this.checked)); //將按鈕狀態傳送到伺服器(作為1或0)
  });
});
socket.on('light', function (data) { //從客戶端獲取按鈕狀態
  document.getElementById("light").checked = data; //根據Raspberry Pi上的按鈕更改複選框
  socket.emit("light", data); //將按鈕狀態傳送回伺服器
});
</script>

</body>
</html>

還有我們的webserver.js檔案

webserver.js

var http = require('http').createServer(handler); //需要http伺服器,並用handler()函式建立伺服器
var fs = require('fs'); //需要檔案系統模組
var io = require('socket.io')(http) //需要socket.io模組並傳遞http物件(伺服器)

http.listen(8080); //監聽8080埠

function handler (req, res) { //建立伺服器
  fs.readFile(__dirname + '/public/index.html', function(err, data) { //讀取public資料夾中的index.html檔案
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'}); //錯誤時顯示404
      return res.end("404 Not Found");
    }
    res.writeHead(200, {'Content-Type': 'text/html'}); //寫入HTML
    res.write(data); //寫入index.html中的資料
    return res.end();
  });
}

io.sockets.on('connection', function (socket) {// WebSocket連線
  var lightvalue = 0; //靜態變數,用於儲存當前狀態
  socket.on('light', function(data) { //從客戶端獲取燈的開關狀態
    lightvalue = data;
    if (lightvalue) {
      console.log(lightvalue); //開啟或關閉LED,目前我們只在控制檯中顯示它
    }
  });
});

讓我們測試一下伺服器

pi@w3demopi:~ $ node webserver.js

使用 http://[RaspberryPi_IP]:8080/ 在瀏覽器中開啟網站

現在伺服器應該將所有複選框的變化輸出到Raspberry Pi上的控制檯中。

客戶端正在傳送變化到伺服器,伺服器正在響應。

讓我們新增由按鈕控制的LED,這是我們之前章節的內容。


新增硬體,並向客戶端傳送響應

讓我們再次更新webserver.js檔案。我們將使用“按鈕控制LED”章節中的許多程式碼。

webserver.js

var http = require('http').createServer(handler); //需要http伺服器,並用handler()函式建立伺服器
var fs = require('fs'); //需要檔案系統模組
var io = require('socket.io')(http) //需要socket.io模組並傳遞http物件(伺服器)
var Gpio = require('onoff').Gpio; //包含onoff以與GPIO互動
var LED = new Gpio(4, 'out'); //使用GPIO引腳4作為輸出
var pushButton = new Gpio(17, 'in', 'both'); //使用GPIO引腳17作為輸入,並處理'both'(按鈕按下和釋放)事件

http.listen(8080); //監聽8080埠

function handler (req, res) { //建立伺服器
  fs.readFile(__dirname + '/public/index.html', function(err, data) { //讀取public資料夾中的index.html檔案
    if (err) {
      res.writeHead(404, {'Content-Type': 'text/html'}); //錯誤時顯示404
      return res.end("404 Not Found");
    }
    res.writeHead(200, {'Content-Type': 'text/html'}); //寫入HTML
    res.write(data); //寫入index.html中的資料
    return res.end();
  });
}

io.sockets.on('connection', function (socket) {// WebSocket連線
  var lightvalue = 0; //靜態變數,用於儲存當前狀態
  pushButton.watch(function (err, value) { //觀察pushButton上的硬體中斷
    if (err) { //如果發生錯誤
      console.error('There was an error', err); //將錯誤訊息輸出到控制檯
      return;
    }
    lightvalue = value;
    socket.emit('light', lightvalue); //將按鈕狀態傳送給客戶端
  });
  socket.on('light', function(data) { //從客戶端獲取燈的開關狀態
    lightvalue = data;
    if (lightvalue != LED.readSync()) { //僅當狀態發生變化時才更改LED
      LED.writeSync(lightvalue); //開啟或關閉LED
    }
  });
});

process.on('SIGINT', function () { //當按下Ctrl+C時
  LED.writeSync(0); //關閉LED
  LED.unexport(); //取消匯出LED GPIO以釋放資源
  pushButton.unexport(); //取消匯出Button GPIO以釋放資源
  process.exit(); //完全退出
});

讓我們測試一下伺服器

pi@w3demopi:~ $ node webserver.js

使用 http://[RaspberryPi_IP]:8080/ 在瀏覽器中開啟網站

現在伺服器應該將所有複選框的變化輸出到Raspberry Pi上的控制檯中。

客戶端正在傳送變化到伺服器,伺服器正在響應。

End the program with Ctrl+c.


×

聯絡銷售

如果您想將 W3Schools 服務用於教育機構、團隊或企業,請傳送電子郵件給我們
sales@w3schools.com

報告錯誤

如果您想報告錯誤,或想提出建議,請傳送電子郵件給我們
help@w3schools.com

W3Schools 經過最佳化,旨在方便學習和培訓。示例可能經過簡化,以提高閱讀和學習體驗。教程、參考資料和示例會不斷審查,以避免錯誤,但我們無法保證所有內容的完全正確性。使用 W3Schools 即表示您已閱讀並接受我們的使用條款Cookie 和隱私政策

版權所有 1999-2024 Refsnes Data。保留所有權利。W3Schools 由 W3.CSS 提供支援