发布于 2026-01-05 7 阅读
0

在Node.js中使用Socket.io发送实时通知

在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>
Enter fullscreen mode Exit fullscreen mode

上面的代码片段通过 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>
Enter fullscreen mode Exit fullscreen mode

对于 React.js、Next.js 和其他 JavaScript 库或框架,您可以通过 NPM 下载 Socket.io 客户端 API。

npm install socket. io-client
Enter fullscreen mode Exit fullscreen mode

要安装后端服务器,您的计算机上至少需要安装 Node.js v10,然后才能通过 NPM 安装服务器 API。

npm install socket.io
Enter fullscreen mode Exit fullscreen mode

借助此库,您可以创建 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
Enter fullscreen mode Exit fullscreen mode

创建 index.js 文件——这是 Web 应用程序的入口点。

touch index.js
Enter fullscreen mode Exit fullscreen mode

安装 Express.js、Nodemon 和 Socket.io。Nodemon 是一个 Node.js 工具,它会在检测到文件更改后自动重启服务器。

npm install express nodemon socket.io
Enter fullscreen mode Exit fullscreen mode

通过在配置文件中将启动命令添加到脚本列表中来配置 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"
  }
}
Enter fullscreen mode Exit fullscreen mode

更新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}`);
});
Enter fullscreen mode Exit fullscreen mode

创建一个 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>
Enter fullscreen mode Exit fullscreen mode

创建一个名为 public 的文件夹。该文件夹将存放 HTML 页面的 CSS 文件。

mkdir public
cd public
touch index.css
Enter fullscreen mode Exit fullscreen mode

将以下代码复制到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;
}
Enter fullscreen mode Exit fullscreen mode

运行Node.js服务器。您可以在Web浏览器中通过https://localhost:8080查看index.html文件。

npm start
Enter fullscreen mode Exit fullscreen mode

在客户端配置 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>
Enter fullscreen mode Exit fullscreen mode
<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>
Enter fullscreen mode Exit fullscreen mode

创建一个 JavaScript 文件,script.js使我们能够通过 JavaScript DOM 访问用户输入和网页上的 HTML 元素。

cd public
touch script.js
Enter fullscreen mode Exit fullscreen mode

通过 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');
Enter fullscreen mode Exit fullscreen mode

创建一个事件监听器,每当表单提交时,将用户提供的消息记录到控制台。

function printMessage(e) {
  e.preventDefault();
  console.log(message.value);
}
button.addEventListener('click', printMessage);
Enter fullscreen mode Exit fullscreen mode

接下来,将 Socket.io 添加到客户端 JavaScript 文件 - script.js 中。

const socket = io();

socket.on('response', (data) => {
  notify.textContent = data;
  messageBar.style.backgroundColor = '#3F4E4F';
  messageBar.style.height = '20vh';
});
Enter fullscreen mode Exit fullscreen mode

上面的代码片段监听来自服务器的标记为 response 的消息。如果有消息,它会将消息显示在网页上。

修改该printMessage函数,使其能够从客户端向 Node.js 服务器发送消息。以下代码片段会在用户点击提交按钮时向服务器发送消息。

function printMessage(e) {
  e.preventDefault();
  socket.emit('message', message.value);
}
Enter fullscreen mode Exit fullscreen mode

将 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}`);
});
Enter fullscreen mode Exit fullscreen mode

从上面的代码片段可以看出,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');
  });
});
Enter fullscreen mode Exit fullscreen mode

上述函数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)
  });
});
Enter fullscreen mode Exit fullscreen mode

*socket.broadcast.emit()- 将数据发送给除您以外的所有人,以及socket.emit()- 将数据发送给连接到服务器的所有人,包括您*

恭喜!🎊 您已完成本教程的项目。

结论

在本教程中,您已经学习了

  • 什么是 WebSocket?
  • 我们为什么以及何时需要 Socket.io?
  • 如何将 Socket.io 连接到 Web 客户端和 Node.js 服务器,以及
  • 如何在HTML客户端和Node.js服务器之间发送消息。

Socket.io 支持私信和群聊,通过昵称识别用户,显示用户是否在线,以及知道用户是否正在输入。

借助 Socket.io 提供的这些功能,您可以构建复杂的实时应用程序,这些应用程序可用于航空、游戏、媒体和金融等各个行业。

Socket.io 是客户端和 Node.js 服务器之间进行实时通信的绝佳选择。其他一些库,例如TwilioFirebaseSupabase等等,也支持实时通信。欢迎了解一下。

感谢阅读,
您可以在这里找到完整的源代码:
https://github.com/novuhq/blog/tree/main/sending%20emails%20via%20SocketIO

文章来源:https://dev.to/novu/sending-real-time-notifications-with-socketio-in-nodejs-1l5j