菜单
×
   ❮     
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 提供支持