likes
comments
collection
share

趁下班时间,简单写了一个在线协同编辑网页

作者站长头像
站长
· 阅读数 17

实现一个简单的协同文档,并以代码说明

以下是一个使用WebSocket和基于操作转换(Operational Transformation,OT)简化策略的简单协同文档实现。在这个示例中,我们仅考虑了插入和删除操作。

首先,创建一个简单的HTML文档,包括一个textarea用于输入文本以及一个div用于显示在线用户:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Collaborative Document</title>
</head>
<body>
  <textarea id="text" rows="10" cols="50"></textarea>
  <div id="online-users"></div>
  <script src="client.js"></script>
</body>
</html>

接下来,创建client.js文件,其中包含客户端代码:

const textArea = document.getElementById('text');
const onlineUsers = document.getElementById('online-users');

// 创建WebSocket连接
const socket = new WebSocket('ws://localhost:3000');

// 当WebSocket连接成功时,向服务器发送一个"join"事件
socket.addEventListener('open', () => {
  socket.send(JSON.stringify({ event: 'join', userId: generateUserId() }));
});

// 监听服务器发送的消息
socket.addEventListener('message', (event) => {
  const data = JSON.parse(event.data);
  switch (data.event) {
    case 'update':
      // 更新文档内容
      textArea.value = data.content;
      break;
    case 'users':
      // 更新在线用户列表
      onlineUsers.textContent = '在线用户: ' + data.users.join(', ');
      break;
  }
});

// 监听文本框的输入事件
textArea.addEventListener('input', (event) => {
  // 将编辑操作发送给服务器
  socket.send(JSON.stringify({ event: 'input', value: textArea.value }));
});

// 生成一个随机用户ID
function generateUserId() {
  return 'user_' + Math.floor(Math.random() * 1000);
}

接下来,创建server.js文件,其中包含服务器端代码。首先,确保已经安装了ws库,可以使用以下命令进行安装:

npm install ws

接着在server.js文件中添加以下代码:

const WebSocket = require('ws');

const server = new WebSocket.Server({ port: 3000 });

const users = new Map();

// 当有新的WebSocket连接时
server.on('connection', (socket) => {
  // 监听客户端发送的消息
  socket.on('message', (message) => {
    const data = JSON.parse(message);
    switch (data.event) {
      case 'join':
        // 用户加入,保存用户信息
        socket.userId = data.userId;
        users.set(socket.userId, socket);
        // 向所有客户端发送更新的用户列表
        broadcast('users', { users: Array.from(users.keys()) });
        break;
      case 'input':
        // 收到客户端的编辑操作,向所有客户端发送更新的文档内容
        broadcast('update', { content: data.value });
        break;
    }
  });

  // 监听连接关闭事件
  socket.on('close', () => {
    // 移除已断开的用户
    users.delete(socket.userId);
    // 向所有客户端发送更新的用户列表
    broadcast('users', { users: Array.from(users.keys()) });
  });
});

// 向所有客户端广播消息
function broadcast(event, data) {
  const message = JSON.stringify({ event, ...data });
  for (const socket of server.clients) {
    if (socket.readyState === WebSocket.OPEN) {
      socket.send(message);
    }
  }
}

console.log('WebSocket server is running on port 3000');

现在,你可以运行服务器代码:

node server.js

然后在多个浏览器窗口中打开index.html文件,就可以看到协同文档的实现。在一个窗口中输入文本时,其他窗口中的文本会实时更新。同时,可以看到在线用户列表的变化。

请注意,这是一个简化的示例,仅用于说明协同文档的基本概念。在实际应用中,你可能需要考虑更多细节和优化,如更精细的操作转换、错误处理、权限管理等。

转载自:https://juejin.cn/post/7241858865943199803
评论
请登录