likes
comments
collection
share

基于 React + Socket.io 实现简易在线文档协作编辑

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

本文将介绍如何使用 React和 Socket.io 实现在线文档协作编辑。在线协作文档编辑是一种非常方便的方式,可以帮助团队在不同的地理位置进行协作工作,提高工作效率。当团队成员在不同的地理位置时,使用在线协作文档编辑工具可以让他们在同一文档中共同编辑文件,同时避免了文件的多个版本,确保了团队成员都在同一页面上工作。

一、 用到的技术栈

该项目中使用的主要技术:

  • React:选择React的原因是因为React是一个功能强大的JavaScript库,可以帮助我们构建可重用的UI组件。React不仅易于学习,而且具有出色的性能和可扩展性。此外,React还具有丰富的社区支持,有大量的第三方库和工具可供选择,可以帮助我们更快地开发应用程序。

  • TypeScript:TypeScript是由微软开发的开源编程语言,它添加了静态类型和基于类的面向对象编程概念到JavaScript中。TypeScript可以帮助开发者编写更可维护和可读性更强的代码,并提供更好的自动化工具支持。

  • Socket.io:Socket.io是一个开源JavaScript库,它提供了实时通信和协作编辑功能。它可以让开发者轻松构建具有实时功能的应用程序,例如聊天应用程序或多人协作编辑工具。Socket.io支持多种传输协议和浏览器,并且具有良好的可扩展性和稳定性。

二、项目运行效果

代码仓库地址:forrestyuan/OnlinedocEditing:(github.com) 如何运行项目:

  1. 克隆项目到本地:git clone <代码仓库>
  2. 安装项目依赖:my-app目录和server下:npm install
  3. 进入server目录:node index.js
  4. 进入my-app目录:yarn start
  5. 在浏览器打开localhost:3000

基于 React + Socket.io 实现简易在线文档协作编辑

三、前端实现

1. 创建一个 React 应用

创建一个新的 React 应用,可以使用 create-react-app 脚手架。create-react-app 是一个自动化工具,可以快速搭建一个基于 React 的项目。它提供了一些预设的配置,如 Babel、Webpack 等,使得你可以更加专注于编写代码而不是繁琐的配置。可以选择使用 TypeScript 或者 JavaScript。可以添加一些常用的库,如 React Router、Redux 等,以实现更多功能。

npx create-react-app my-app --template typescript

2. 安装 Socket.io 客户端

使用 yarn 或 npm 安装 Socket.io 客户端。

yarn add socket.io-client

3. 实现 Socket.io连接

在 React 组件中使用 Socket.io客户端连接到服务器端。

import io from 'socket.io-client';
const socket = io('http://localhost:3333');

4. 实现协作编辑功能

使用 Socket.io 实现实时通信和协作编辑功能,并使用 React 和 ReactQuill 来实现UI界面。其中,ReactQuill 是一个富文本编辑器,可以让用户更方便地进行文本编辑。在这个在线文档协作编辑器中,用户可以在同一文档中共同编辑文件。

在代码中Socket 是用于描述 socket.io-client 库中 socket 实例的类型。如果不存在这个类型,可能是因为没有正确地安装 @types/socket.io-client 类型声明文件。可以通过以下命令安装:

npm install @types/socket.io-client

安装完成后,重新编译项目,应该就可以使用Socket 类型了。

5. 美化页面

然后添加以下样式规则:

.app{
  display: flex;
  flex-direction: column;
}
.header{
  text-align: center;
  margin-bottom: 10px;
  background-color: #333;
  color:white;
}
.header a{
  color:#fff;
  text-decoration: none;
}
.container {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  height: 86vh;
}

.editor {
  width: 80%;
  margin: 0 auto;
  padding: 0 10px 0 0;
  box-sizing: border-box;
}
.editor .ql-editor{
  height:82vh;
}
.user-list {
  width: 20%;
  margin-right: 2rem;
  border-right: solid #ccc 1px;
  padding-left: 10px;
  box-sizing: border-box;
}

.user-list ul {
  list-style: none;
  padding:0 10px 0 0;
  height: 79vh;
}

.user-list li {
  margin-bottom: 0.5rem;
  font-size: 14px;
  background-color: #444;
  color: #FFF;
  padding:2px 0 2px 5px;
  border-radius: 10px;
}

.user-list .editing::after {
  content: "(正在编辑)";
  color:yellow;
  font-size: 12px;
  margin-left: 5px;
}

这将为 .container 添加一个居中的样式,并将 .editor.user-list 分别设置为文本编辑器和在线用户列表的容器,并设置用户列表的样式。同时,设置文本编辑器的样式,以适应页面布局。

四、后端实现

1. 创建一个 Node.js 应用

使用 Node.js 创建一个新的应用。新建一个server文件夹,cd到server文件夹下面,执行以下命令

npm init -y

然后创建一个index.js 文件,用于编写服务端代码。

2. 安装 Socket.io服务端

使用 yarn 或 npm 安装 Socket.io 服务端。

npm install socket.io

3. 实现 Socket.io连接

在 Node.js 应用中使用 Socket.io服务端建立连接并监听客户端事件。

http模块创建了一个 httpServer 实例,并使用 socket.io 将其升级为 WebSocket 服务器。创建一个 users 集合用于存储所有已连接的用户的 socket.id。当有用户连接时,将其 socket.id 添加到 users 集合中,并向此用户发送一个 connectUser 事件,并向所有已连接的用户广播一个 users 事件,以更新在线用户列表。

当有用户断开连接时,它会从 users 集合中删除该用户的 socket.id,并向所有已连接的用户广播一个 users 事件,以更新在线用户列表。

const httpServer = require('http').createServer();
const io = require('socket.io')(httpServer, {
  cors: {
    origin: '*',
  },
});

const users = new Set();
let existingText = ''
let editingUser = '';

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

  users.add(socket.id);
  socket.emit('connectUser', socket.id);
  socket.emit('text', existingText);
  io.emit('users', Array.from(users));

  socket.on('text', (newText) => {
    existingText = newText;
    io.emit('text', newText);
  });

  socket.on('editing', (userId) => {
    editingUser = userId
    io.emit('editing', userId)
  })

  socket.on('disconnect', () => {
    console.log('user disconnected');
    users.delete(socket.id);
    if (editingUser === socket.id) {
      editingUser = '';
      io.emit('editing', '');
    }
    io.emit('users', Array.from(users));
  });
});

httpServer.listen(3333, () => {
  console.log('listening on *:3333');
});

socket.emit 是用于发送事件到指定的 socket 对象,只有该 socket 对象会收到该事件,其他任何 socket 对象都不会收到该事件。

io.emit 是用于向所有连接到服务器的 socket 对象广播事件,所有连接到服务器的 socket 对象都会收到该事件。

在实现在线文档协作编辑的场景中,使用 io.emit 可以确保所有连接到服务器的用户都能够收到其他用户所做的更改,从而保证协作效率。

五、待补充功能

当前实现的这个版本功能尚比较简单,要实现类似于飞书那样的在线文档协作,需要考虑更多功能。

  • 实现协作文档的分享功能,可以将文档分享给其他用户或团队成员
  • 实现文档的自动保存功能,避免因意外断电或网络故障导致数据丢失
  • 实现多种编辑模式,例如代码模式、预览模式、全屏模式等
  • 实现协作文档的导出功能,可以将文档导出为多种格式,例如 PDF、DOC、HTML 等
  • 实现文档的标签管理功能,可以为文档添加标签,方便进行分类和检索
  • 实现文档的评论和反馈功能,方便用户之间进行交流和留言
  • 实现多语言支持,使得用户可以选择自己熟悉的语言进行协作编辑

才思如泉涌的你有兴趣完善吗。

六、写在最后

本文介绍了如何使用 React 和 Socket.io实现在线文档协作编辑。在实现这一功能的过程中,我们还需要注意一些事项。例如,我们需要考虑到不同用户之间的权限和编辑范围,以防止误操作和不必要的冲突。此外,我们还可以添加一些额外的功能,比如历史记录和版本控制,以便于用户进行版本管理和文档追溯。总之,使用 React 和 Socket.io实现在线文档协作编辑是一种非常实用的技术,可以极大地提高工作效率和协作效果。

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