在Node.js中使用Socket.io发送实时通知
网站是如何运作的?
- 用户向网络浏览器提供网址。
- 浏览器向网络服务器发送请求,请求与 URL 相关的资源。
- 服务器收到请求后,会向网页浏览器发送包含相关文件的HTTP响应。
- 浏览器将响应以网页的形式显示给用户。
这种通信方式是 HTTP 连接,适用于数据不经常更改的应用场景。
你是否使用过外汇交易应用程序或访问过体育博彩网站?你会注意到数据几乎每分钟都在变化;这些变化是借助 WebSocket 技术实现的。
WebSocket 在客户端和服务器之间建立连接,允许它们双向发送数据,包括客户端到服务器和服务器到客户端。与 HTTP 相比,WebSocket 提供持久的双向客户端-服务器连接,使得数据可以实时更新而无需刷新页面。
诺武
如果您正在寻找应用内通知解决方案(类似于 Facebook、Instagram、Upwork 等),不妨了解一下 Novu,我们为您提供完整的解决方案,无需处理 WebSocket、扩展、数据库或服务器等问题。快来给我们点个赞吧⭐️🤩
https://github.com/novuhq/novu
我们回来了!
Node.js 有一个内置的 WebSocket 模块,但该模块没有提供构建复杂实时应用程序所需的功能;这就是 Socket.io 存在的原因。
Socket.io是一个流行的 JavaScript 库,它允许我们在客户端和 Node.js 服务器之间创建实时双向通信。它性能卓越且可靠,经过优化,能够以最小的延迟处理大量数据消息。它遵循 WebSocket 协议,并提供更强大的功能,例如回退到 HTTP 长轮询或自动重连,从而使我们能够构建高效的聊天和实时 Web 应用程序。
本文将介绍如何使用 Socket.io 在 Web 客户端和 Node.js 服务器之间发送通知。在开始编写代码之前,让我们先了解一下 Socket.io 的工作原理。
本教程假设您已具备使用 Express.js 和 Node.js 构建 Web 应用程序的基本知识。
Socket.io库的工作原理是什么?
实时 Node.js 应用,例如外汇交易、体育博彩网站、聊天应用等等,都使用 Socket.io。在本节中,您将学习 Socket.io 如何在 Web 应用中实现客户端和服务器之间的消息传输。
Socket.io库包含两部分——客户端 API 和服务器端 API。客户端 API 使用户能够通过 WebSocket 连接到服务器,而服务器端 API 则在后端服务器上发起 Socket.io 连接。
要将 Socket.io 连接到 Web 客户端,您需要通过 CDN 或 NPM 下载客户端 JavaScript 包。
对于 HTML 客户端,请将此代码添加到 head 标签内。
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js" integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k" crossorigin="anonymous"></script>
上面的代码片段通过 CDN 下载 Socket.io,并将客户端包暴露/socket.io/socket.io.js给客户端。然后,我们可以通过将以下代码添加到 HTML body 标签的底部来访问 Socket.io。
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
</script>
对于 React.js、Next.js 和其他 JavaScript 库或框架,您可以通过 NPM 下载 Socket.io 客户端 API。
npm install socket. io-client
要安装后端服务器,您的计算机上至少需要安装 Node.js v10,然后才能通过 NPM 安装服务器 API。
npm install socket.io
借助此库,您可以创建 Socket.io 连接,将 Web 客户端连接到后端服务器,并开始在客户端和服务器之间发送消息。
但这只是对 Socket.io 工作原理的简单解释。在本文中,我将通过构建一个通知系统,逐步指导您如何在客户端和服务器端添加 Socket.io 库。
在 Node.js 服务器上配置 Express.js
本文将指导您如何在 Node.js 服务器上部署 Express.js。Express.js 是一个快速、简洁的框架,为构建 Node.js Web 应用程序提供了多种功能。它使我们能够为 Node.js 应用程序创建 Web 客户端。
创建一个文件夹来存放我们的应用程序。然后,package.json运行以下代码创建一个文件。
mkdir <folder-name>
cd <folder-name>
npm init -y
创建 index.js 文件——这是 Web 应用程序的入口点。
touch index.js
安装 Express.js、Nodemon 和 Socket.io。Nodemon 是一个 Node.js 工具,它会在检测到文件更改后自动重启服务器。
npm install express nodemon socket.io
通过在配置文件中将启动命令添加到脚本列表中来配置 Nodemon package.json。以下代码片段使用 Nodemon 启动服务器。
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon index.js" //npm start - starts the server with Nodemon
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.1",
"nodemon": "^2.0.19",
"socket.io": "^4.5.1"
}
}
更新index.js文件以渲染HTML页面。将以下代码复制到index.js文件中。
const express = require('express');
const app = express();
const path = require('path');
const PORT = process.env.PORT || 8080;
//enables us to host static CSS & JS files.
//The public folder contains the CSS & JS files.
app.use(express.static('public'));
//Route to the homepage of the application
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/index.html'));
});
//Listens for changes in the web application
app.listen(PORT, () => {
console.log(`App listening at ${PORT}`);
});
创建一个 index.html 文件,用于显示消息栏和按钮。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Socket IO Chat App</title>
<!-- Link to CSS file-->
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div id="message-bar">
<p id="notification"></p>
</div>
<form class="container">
<h2>Send Messages with Socket.io</h2>
<textarea
rows="5"
width="100%"
name="message"
id="message"
placeholder="Enter your message..."
></textarea>
<button>SEND MESSAGE</button>
</form>
</body>
</html>
创建一个名为 public 的文件夹。该文件夹将存放 HTML 页面的 CSS 文件。
mkdir public
cd public
touch index.css
将以下代码复制到index.css文件中
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Poppins', sans-serif;
}
#message-bar {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
}
#notification {
color: #fff;
}
.container {
height: 80vh;
width: 100%;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: center;
}
h2 {
text-align: center;
margin-bottom: 30px;
}
textarea {
font-size: 16px;
margin-bottom: 30px;
padding: 15px;
outline: none;
}
button {
width: 200px;
padding: 15px;
cursor: pointer;
background-color: #2c3639;
outline: none;
border: none;
color: #dcd7c9;
font-size: 16px;
}
button:hover {
background-color: #3f4e4f;
}
运行Node.js服务器。您可以在Web浏览器中通过https://localhost:8080查看index.html文件。
npm start
在客户端配置 Socket.io
在本节中,我将引导您完成将 Web 客户端连接到 Socket.io 的过程。
更新index.html文件以通过 CDN 连接 Socket.io JavaScript 包。将第一段代码添加到 head 标签内,另一段代码添加到 body 标签的底部。
<head>
<!-- This links to Socket.io client JavaScript bundle via CDN. -->
<script
src="https://cdn.socket.io/4.5.0/socket.io.min.js"
integrity="sha384-7EyYLQZgWBi67fBtVxw60/OWl1kjsfrPFcaU0pp0nAh+i8FD068QogUvg85Ewy1k"
crossorigin="anonymous"
></script>
</head>
<body>
......
The page content
.....
<!-- Link to the JavaScript file-->
<script src="./script.js" type="module"></script>
<!-- This access the client JavaScript bundle provided via its CDN -->
<script src="/socket.io/socket.io.js"></script>
</body>
创建一个 JavaScript 文件,script.js使我们能够通过 JavaScript DOM 访问用户输入和网页上的 HTML 元素。
cd public
touch script.js
通过 JavaScript 提供的文档对象模型访问 HTML 元素。
//In script.js
const notify = document.querySelector('#notification');
const message = document.querySelector('#message');
const button = document.querySelector('button');
const messageBar = document.querySelector('#message-bar');
创建一个事件监听器,每当表单提交时,将用户提供的消息记录到控制台。
function printMessage(e) {
e.preventDefault();
console.log(message.value);
}
button.addEventListener('click', printMessage);
接下来,将 Socket.io 添加到客户端 JavaScript 文件 - script.js 中。
const socket = io();
socket.on('response', (data) => {
notify.textContent = data;
messageBar.style.backgroundColor = '#3F4E4F';
messageBar.style.height = '20vh';
});
上面的代码片段监听来自服务器的标记为 response 的消息。如果有消息,它会将消息显示在网页上。
修改该printMessage函数,使其能够从客户端向 Node.js 服务器发送消息。以下代码片段会在用户点击提交按钮时向服务器发送消息。
function printMessage(e) {
e.preventDefault();
socket.emit('message', message.value);
}
将 Socket.io 添加到 Node.js 服务器
在本节中,您将学习如何在Node.js服务器上配置Socket.io,并且您可以通过Socket.io接收和发送来自客户端的消息。
更新 index.js 文件,导入 Node.js 的 Socket.io 和 HTTP 模块。HTTP 模块会创建一个 HTTP 服务器,使 Node.js 能够通过网络传输数据。
const express = require('express');
const app = express();
const path = require('path');
const PORT = process.env.PORT || 8080;
//New imports
const http = require('http').Server(app);
//Pass the Express app into the HTTP module.
const socketIO = require('socket.io')(http);
app.use(express.static('public'));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, '/index.html'));
});
//Listen for changes on the HTTP server not the Express server
http.listen(PORT, () => {
console.log(`App listening at ${PORT}`);
});
从上面的代码片段可以看出,HTTP 服务器接受 Express 应用程序作为参数,并且我们监听 HTTP 服务器上的变化,而不是监听 Express 上的变化。
在执行代码块之前app.get(),使用 Socket.io 创建与 Web 客户端的连接。
socketIO.on('connection', (socket) => {
console.log(`⚡: ${socket.id} user just connected`);
socket.on('disconnect', () => {
console.log('A user disconnected');
});
});
上述函数socket.io("connection")会与 Web 客户端建立连接。Socket.io 会为每个客户端创建一个唯一的 ID,并在用户访问网页时将该 ID 记录到控制台。当用户刷新或关闭网页时,Socket 会触发断开连接事件,表明用户已断开与 Socket 的连接。
接下来,更新函数以向客户端发送和接收数据。
socketIO.on('connection', (socket) => {
console.log(`⚡: ${socket.id} user just connected`);
socket.on('disconnect', () => {
console.log('A user disconnected');
});
socket.on('message', (data) => {
//sends the data to everyone except you.
socket.broadcast.emit('response', data);
//sends the data to everyone connected to the server
// socket.emit("response", data)
});
});
*socket.broadcast.emit()- 将数据发送给除您以外的所有人,以及socket.emit()- 将数据发送给连接到服务器的所有人,包括您*
恭喜!🎊 您已完成本教程的项目。
结论
在本教程中,您已经学习了
- 什么是 WebSocket?
- 我们为什么以及何时需要 Socket.io?
- 如何将 Socket.io 连接到 Web 客户端和 Node.js 服务器,以及
- 如何在HTML客户端和Node.js服务器之间发送消息。
Socket.io 支持私信和群聊,通过昵称识别用户,显示用户是否在线,以及知道用户是否正在输入。
借助 Socket.io 提供的这些功能,您可以构建复杂的实时应用程序,这些应用程序可用于航空、游戏、媒体和金融等各个行业。
Socket.io 是客户端和 Node.js 服务器之间进行实时通信的绝佳选择。其他一些库,例如Twilio、Firebase、Supabase等等,也支持实时通信。欢迎了解一下。
感谢阅读,
您可以在这里找到完整的源代码:
https://github.com/novuhq/blog/tree/main/sending%20emails%20via%20SocketIO
