实现实时推送通知:WebSocket

雨后彩虹 2020-11-13 ⋅ 4 阅读

在传统的 Web 开发中,客户端向服务器发送请求,服务器处理请求后返回响应给客户端。但是,这种方式无法实现实时的双向通信。在一些实时通信的场景中,比如聊天室、实时某些事件的提醒等,需要一种可靠的方式来实现实时推送通知。

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议,可以实现实时的双向通信。它允许客户端和服务器之间的实时数据交换,而无需通过轮询或者长轮询的方式。本文将介绍如何使用 WebSocket 实现一个简单的实时推送通知的服务器。

准备工作

在开始之前,我们需要安装一些依赖。

  1. Node.js:请确保你的电脑上安装了最新版本的 Node.js 运行环境。
  2. Express.js:一个简易、快速、灵活的 Node.js Web 应用框架,用于快速搭建服务器。

首先,在项目文件夹中创建一个 package.json 文件,并填写如下内容:

{
  "name": "websocket-notification-server",
  "version": "1.0.0",
  "description": "WebSocket Notification Server",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  },
  "dependencies": {
    "express": "^4.17.1",
    "websocket": "^1.0.31"
  }
}

然后,在项目文件夹中打开终端,执行以下命令安装依赖:

$ npm install

创建 WebSocket 服务器

接下来,我们将创建一个 index.js 文件作为 WebSocket 服务器的入口文件。

const express = require('express');
const WebSocket = require('websocket').server;

// 创建 Express 应用实例
const app = express();

// 设置静态文件目录
app.use(express.static('public'));

// 创建 HTTP 服务器并将 Express 应用实例作为回调函数传入
const server = require('http').createServer(app);

// 实例化 WebSocket 服务器并传入 HTTP 服务器实例
const wsServer = new WebSocket({ httpServer: server });

// 客户端列表
const clients = [];

// 当有 WebSocket 连接请求时触发回调函数
wsServer.on('request', (request) => {
  // 接受连接请求
  const connection = request.accept(null, request.origin);

  // 客户端连接成功后将其添加到客户端列表
  clients.push(connection);

  // 当接收到客户端消息时触发回调函数
  connection.on('message', (message) => {
    // 遍历所有客户端并发送消息
    clients.forEach((client) => {
      client.send(message.utf8Data);
    });
  });

  // 当客户端断开连接时触发回调函数
  connection.on('close', (reasonCode, description) => {
    // 将断开连接的客户端从列表中移除
    clients.splice(clients.indexOf(connection), 1);
  });
});

// 监听指定端口
server.listen(3000, () => {
  console.log('Server started on http://localhost:3000');
});

上述代码中,我们首先通过 require 引入 expresswebsocket 两个依赖,并实例化一个 Express 应用。然后,创建一个 HTTP 服务器并将 Express 应用实例作为回调函数传入。接着,我们使用 websocketServer 类创建一个 WebSocket 服务器实例,并传入 HTTP 服务器实例。之后,我们定义了一个客户端列表用于存储连接到服务器的客户端。

在 WebSocket 的 request 事件回调函数中,我们首先接受连接请求,然后将连接添加到客户端列表中。接着,我们定义了 message 事件回调函数,当接收到客户端发来的消息时,遍历所有客户端并将消息发送给每个客户端。最后,我们定义了 close 事件回调函数,当客户端断开连接时,将断开连接的客户端从列表中移除。

最后,在服务器监听指定端口后,我们在控制台输出服务器运行的地址。

前端页面

在项目的根目录中创建一个 public 文件夹,作为静态文件目录。然后,在 public 文件夹中创建一个 index.html 文件,并填写如下内容:

<!DOCTYPE html>
<html>
<head>
  <title>WebSocket Push Notifications</title>
</head>
<body>
  <h1>WebSocket Push Notifications</h1>

  <input type="text" id="notificationInput" placeholder="Enter your notification">
  <button onclick="sendNotification()">Send Notification</button>

  <ul id="notificationsList"></ul>

  <script>
    const socket = new WebSocket('ws://localhost:3000');

    // 当连接成功时触发事件
    socket.onopen = () => {
      console.log('WebSocket connection established.');
    };

    // 当接收到服务器发送的消息时触发事件
    socket.onmessage = (event) => {
      const notificationsList = document.getElementById('notificationsList');
      const newNotification = document.createElement('li');
      newNotification.textContent = event.data;
      notificationsList.appendChild(newNotification);
    };

    // 当连接关闭时触发事件
    socket.onclose = () => {
      console.log('WebSocket connection closed.');
    };

    function sendNotification() {
      const notificationInput = document.getElementById('notificationInput');
      const notification = notificationInput.value;

      if (notification.trim() !== '') {
        socket.send(notification);
        notificationInput.value = '';
      }
    }
  </script>
</body>
</html>

上述代码中,我们使用 WebSocket 的 WebSocket 类创建一个 WebSocket 实例,并指定连接到的服务器的 URL。在 onopen 事件回调函数中,判断连接是否成功建立。在 onmessage 事件回调函数中,我们接收到服务器发送的消息后,在页面中创建一个列表项显示接收到的消息。在 onclose 事件回调函数中,判断连接是否关闭。最后,我们定义了 sendNotification 函数用于获取输入框中的内容,并发送给服务器。

运行服务器

最后,在项目文件夹中打开终端,执行以下命令运行服务器:

$ npm start

在浏览器中打开 http://localhost:3000,即可看到一个简单的实时推送通知的页面。你可以在输入框中输入内容,并点击 "Send Notification" 按钮,即可将通知实时推送给其他相连的客户端。

至此,我们已经成功实现了一个简单的 WebSocket 推送服务器,实现了实时推送通知的功能。但是,这只是一个开始,你可以根据实际需求进行扩展,比如对连接进行身份验证、添加更多的事件处理逻辑、优化性能等。祝你使用愉快!


全部评论: 0

    我有话说: