基于 React + Socket.io 实现简易在线文档协作编辑
本文将介绍如何使用 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) 如何运行项目:
- 克隆项目到本地:
git clone <代码仓库>- 安装项目依赖:my-app目录和server下:
npm install- 进入server目录:
node index.js- 进入my-app目录:
yarn start- 在浏览器打开
localhost:3000

三、前端实现
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