基于 Node.js 实现多人实时协作编辑

在现代 web 开发领域,实时多人协作编辑已经成为了广泛被使用的功能。对于很多产品而言,协作编辑是实现多人实时交流、评论、协同编辑等重要功能的基础。在本文中,我们将介绍如何基于 Node.js 实现多人实时协作编辑。

实现方式

实时协作编辑的实现方式有多种,其中比较常见的是采用 WebSocket 技术,以及共享数据或者采用协议传输技术进行实现。在本文中,我们选用了 WebSocket 技术实现多人实时协作编辑。

功能分析

在开始具体介绍实现细节前,我们先来分析一下需要实现的功能:

  1. 多人加入同一个编辑页面能实时看到彼此操作的内容
  2. 任何人在该编辑页面进行的任何操作都可以同步协同展示给其他所有人
  3. 可以显示每个用户的光标位置以便其他用户可见

接下来,我们将详细介绍如何实现这些功能。

使用 Socket.IO 实现实时通信

为了完成实时协作编辑,我们选择使用 Socket.IO 库实现 WebSocket 通信。WebSocket 是一种在单个 TCP 连接上进行全双工通信的网络协议,用于使客户端浏览器和服务器之间实现实时双向通信,轻松处理多用户同时连接的问题。

安装和实例化 Socket.IO

使用 Node.js 以及 npm 包管理器,我们可以在命令行中输入以下命令来安装 Socket.IO:

npm install socket.io --save

示例代码如下:

const server = require('http').createServer();
const io = require('socket.io')(server);

io.on('connection', (socket) => {
  console.log('user connected');
});

server.listen(3000);

以上代码中,我们首先创建 Node.js 的 http 服务器。然后使用 socket.io() 构造函数实例化 Socket.IO 对象。最后,我们监听了 connection 事件,并在其中进行了简单的日志打印。

实现实时编辑

下面,我们将扩展 Socket.IO 的功能,以便在多人同时编辑的情况下,在每个编辑客户端之间实时通信。

服务端实现

样例代码如下:

const server = require('http').createServer();
const io = require('socket.io')(server);

let text = '';
let cursors = {};

io.on('connection', (socket) => {
  console.log('user connected');

  // 初始化新用户的光标
  cursors[socket.id] = {
    x: 0,
    y: 0,
  };

  // 发送文本
  socket.emit('text', text);

  // 发送光标位置
  io.emit('cursors', cursors);

  // 接收文本变更
  socket.on('text', (data) => {
    console.log('text changed', data);
    text = data;
    socket.broadcast.emit('text', text);
  });

  // 接收光标位置变更
  socket.on('cursor', (data) => {
    cursors[socket.id] = data;
    io.emit('cursors', cursors);
  });

  // 用户断开连接
  socket.on('disconnect', () => {
    delete cursors[socket.id];
    io.emit('cursors', cursors);
    console.log('user disconnected');
  });
});

server.listen(3000);

首先我们创建了一个空的字符串变量 text 用于存储文本,一个空对象 cursors 用于存储每个用户的光标位置。

在每个用户连接 Socket.IO 时,我们将初始化一个新的空光标,然后将所有的光标位置向所有客户端广播。

之后,我们在用户断开连接的事件中删除对应的光标。

我们代码中的逻辑从如下五个部分组成:

  1. 初始化新用户的光标
  2. 发送文本
  3. 发送光标位置
  4. 接收文本变更
  5. 接收光标位置变更

客户端实现

样例代码如下:

<!DOCTYPE html>
<html>
  <head>
    <title>Realtime multi-user collaboration editing with Node.js and Socket.IO</title>
  </head>
  <body>
    <textarea id="editor"></textarea>
    <script src="/socket.io/socket.io.js"></script>
    <script>
      const socket = io();

      const editor = document.getElementById('editor');
      const cursor = document.createElement('div');
      cursor.classList.add('cursor');
      document.body.appendChild(cursor);

      let userCursor = {};
      cursor.style.left = '0px';
      cursor.style.top = '0px';

      editor.onkeydown = () => {
        socket.emit('text', editor.value);
      };

      editor.onmousemove = (e) => {
        userCursor = {
          x: e.pageX,
          y: e.pageY,
        };

        cursor.style.left = userCursor.x + 'px';
        cursor.style.top = userCursor.y + 'px';
        socket.emit('cursor', userCursor);
      };

      socket.on('text', (data) => {
        editor.value = data;
      });

      socket.on('cursors', (data) => {
        const cursors = document.querySelectorAll('.cursor');
        Array.from(cursors).forEach((cursor) => cursor.remove());

        Object.keys(data).forEach((key) => {
          const cursor = document.createElement('div');
          cursor.classList.add('cursor');
          document.body.appendChild(cursor);
        });
      });
    </script>
    <style>
      .cursor {
        position: absolute;
        width: 2px;
        background: red;
        z-index: 100;
      }
    </style>
  </body>
</html>

在客户端代码中,我们首先使用 Socket.IO 客户端库来建立一个到服务器的 WebSocket 连接。然后,我们创建并监听多个 DOM 事件,以便对文本和光标位置进行处理并发送给服务器。最后,当客户端收到服务器发送的更新数据时,我们用它来更新 DOM 并更新光标位置。

总结

以上就是基于 Node.js 实现多人实时协作编辑的一个简单实现。它所涉及的技术包括 Socket.IO、WebSocket 等,通过 Socket.IO 建立 WebSocket 连接并进行实时通信。

实时协作编辑的功能不仅是现代网页开发中的一个必需品,同时也充满了挑战性。相信今后在实践之中,我们会遇到更多有趣的应用场景以及解决更多问题的需求。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/659126c7eb4cecbf2d660af5


纠错
反馈