长连接的钟表程序

发布于:2024-06-16 ⋅ 阅读:(157) ⋅ 点赞:(0)

实验要求

实现1个钟表程序(服务),多个用户可以从该程序获得时间并在本地显示,用户也可以修改时间。

(1)用户程序可以在计算机上运行,也可以在手机上运行;

(2)至少3个用户程序可同时运行,时间每秒钟刷新;

   (3) 1个用户修改了时间,所有用户的时间都要随着被改变;

   (4) 推荐使用JavaScript、node.js、Websocket,以及Nginx实现;

   (5) 可能存在跨域问题。

实验步骤

1. 准备环境和安装依赖:

计算机上安装 Node.js 和 npm

创建一个新的文件夹,比如 "realtime-server",进入该文件夹。

在终端中执行以下命令以初始化一个新的 Node.js 项目:

npm init -y 

安装所需的依赖:

npm install express http ws moment cors 
2. 编写代码:

创建一个名为 server.js 的文件,并将提供的代码复制粘贴到该文件中。

3. 运行服务器:

在终端中运行以下命令启动服务器:

node server.js 
4. 连接到服务器:

可使用任何支持 WebSocket 的客户端连接到该服务器。可以使用浏览器的控制台或者 WebSocket 客户端工具,如 wscat

打开浏览器控制台或运行 wscat -c ws://localhost:8080(确保端口号与服务器代码中指定的一致)连接到服务器。

5. 接收当前时间:

一旦连接建立,服务器会发送当前时间给客户端。

6. 发送消息更新时间:

在客户端(浏览器控制台或 wscat)中发送一个符合 ISO 8601 格式的时间字符串,服务器会更新时间并广播给所有连接的客户端。

7. 观察时间更新:

你会看到连接的客户端接收到新的时间,并且每秒钟都会更新一次。

8. 测试不合法时间:

尝试发送一个不符合 ISO 8601 格式的字符串到服务器,你会看到服务器会打印出 "Invalid date format" 的错误信息。

9.结束实验:

关闭服务器,按下 Ctrl + C 终止运行 node server.js 的命令。

这样就能成功地建立了一个实时时间更新的 WebSocket 服务器,并能够通过客户端与其进行交互。

程序代码

服务端server.js

const express = require('express');
const http = require('http');
const WebSocket = require('ws');
const moment = require('moment');

const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
const cors = require('cors');

let currentTime = moment();
let modifiedTime = null; // 变量用于存储用户修改后的时间
app.use(cors());

wss.on('connection', (ws) => {
    ws.send(currentTime.toISOString());

    ws.on('message', (message) => {
        const messageStr = message.toString(); // 将接收到的消息转换为字符串
        if (moment(messageStr, moment.ISO_8601, true).isValid()) {
            modifiedTime = moment(messageStr);
            currentTime = modifiedTime; // 更新当前时间为用户修改后的时间
            wss.clients.forEach((client) => {
                if (client.readyState === WebSocket.OPEN) {
                    client.send(currentTime.toISOString());
                }
            });
        } else {
            console.log('Invalid date format:', messageStr);
        }
    });
});


setInterval(() => {
    if (modifiedTime) {
        currentTime = modifiedTime;
    } else {
        currentTime = moment();
    }
    wss.clients.forEach((client) => {
        if (client.readyState === WebSocket.OPEN) {
            client.send(currentTime.toISOString());
        }
    });
}, 1000);

server.listen(8080, () => {
    console.log('Server started on port 8080');
});

客户端Real-clock.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Real-time Clock</title>
  <script src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
</head>
<body>
  <h1 id="clock"></h1>
  <label for="newTime">Enter New Time:</label>
  <input type="datetime-local" id="newTime" placeholder="YYYY-MM-DDTHH:mm">
  <button onclick="updateTime()">Update Time</button>


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

    socket.onmessage = function(event) {
      const currentTime = moment(event.data).format('YYYY-MM-DD HH:mm:ss');
      document.getElementById('clock').innerText = currentTime;
    };

    function updateTime() {
      const inputDateTime = document.getElementById('newTime').value;
      const formattedDateTime = moment(inputDateTime, 'YYYY-MM-DDTHH:mm').toISOString();
      socket.send(formattedDateTime);
    }

    setInterval(() => {
      socket.send('update');
    }, 1000);
  </script>
</body>
</html>

实验截图

打开 HTML 页面:

将提供的 HTML 代码保存为Real-clock.html 文件,并在浏览器中打开。

2. 初始显示:

页面加载后,你会看到一个标题为 "Real-time Clock" 的页面,以及一个空白的时钟显示区域和一个用于输入新时间的输入框。

钟表程序

3. 连接到服务器:

页面加载后,客户端会尝试连接到 ws://localhost:8080 这个 WebSocket 服务器。

4. 接收当前时间:

一旦连接建立,服务器会发送当前时间给客户端,并显示在页面上的时钟区域。

三个浏览器窗口模拟三个进程

三个浏览器窗口模拟三个进程

5. 输入新时间:

在 "Enter New Time" 输入框中输入一个新的时间,格式为 "YYYY-MM-DDTHH

",例如 "2024-06-15T10:00"。

6. 更新时间:

点击 "Update Time" 按钮,客户端会将新时间发送到服务器,服务器接收并更新时间。

7. 观察时钟更新:

页面上的时钟区域会显示为新输入的时间。

8. 定时更新:

每隔一秒,客户端会向服务器发送一个 "update" 消息,服务器会将当前时间发送回客户端,页面上的时钟区域会持续更新。

9. 结束交互:

关闭浏览器标签或停止服务器,结束交互。

存在的问题:

在这个实验中,存在一些潜在的问题和改进空间:

- 时区处理:当前实现中并未考虑时区的处理,如果需要支持不同时区的用户,需要进一步处理时区转换和显示。

- 客户端错误处理:客户端发送的新时间格式错误时,并未提供友好的提示,用户可能无法得知输入的格式有误。

- 服务器端数据持久化:当前实现中,服务器端并未对时间数据进行持久化,一旦服务器重启,时间会被重置。可以考虑使用数据库或者其他持久化方式来保存时间数据。

 实验展望:

虽然这个实验已经实现了基本的实时时间更新功能,但仍有一些方面可以进一步改进和扩展:

- 用户体验优化:可以进一步改进页面布局和交互方式,使用户能够更方便地输入新时间,并提供更友好的界面反馈。

- 安全性考虑:在生产环境中,需要考虑 WebSocket 连接的安全性,防止恶意攻击和非授权访问。可以考虑添加身份验证、消息加密等安全机制。

- 性能优化:当前的实现每秒都向客户端发送时间更新,即使时间并未发生变化。可以通过在服务器端和客户端实现更智能的逻辑,减少不必要的数据传输,从而提升性能和效率。

实验总结:

在这个实验中,我们成功地构建了一个实时时间更新的 WebSocket 服务器,并通过一个 HTML 页面与之进行交互。以下是实验的主要收获和总结:

- 功能实现:通过使用 Express、WebSocket 和 Moment.js 等技术,我们成功地创建了一个实时时间更新的服务器,并能够通过 WebSocket 实现与客户端的实时通信。

- 页面交互:在 HTML 页面中,我们通过 WebSocket 接收来自服务器的时间更新,并能够通过输入框向服务器发送新的时间来更新时钟显示。

- 定时更新:我们实现了定时向服务器发送更新请求的功能,以保持页面上的时钟实时更新。

(笔者将会非常感谢大家来完善这个程序!)


网站公告

今日签到

点亮在社区的每一天
去签到