1. 多人共同编辑
协同编辑指在同一个文档中,能够与他人合作编写,可以实时看到别人更改的内容,他人也能观察到自己修改的内容。
本文档记录了对该功能的简单实现的学习与开发过程。
2. 技术框架
-
Websocket 协议
WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种。在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后浏览器和服务端之间就形成了一条快速通道,两者之间就直接可以数据相互传送。</br> -
Socket.io 库
socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。
Socket.io支持及时、双向、基于事件的交流,可在不同平台、浏览器、设备上工作,可靠性和速度稳定。
Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。</br> -
NodeJS 环境
Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。Node.js是一个事件驱动I/O服务端JavaScript环境,基于Google的V8引擎,V8引擎执行Javascript的速度非常快,性能非常好。
使用了基于 Node.JS 的 web 框架:express
3. 实现过程
-
3.1 编写主页面 index.html
- 提供一个选择文件按钮、一个保存按钮以及文本编辑区域
<input id='selectfile' type='file' accept='text/plain' onchange='openFile(event)'> <textarea id='output' class="notifyDetail"></textarea> <button id='btn_save' type="submit">Save</button>
-
使用 js实现简单的功能
- 选择文件
var openFile = function(event) { var input = event.target; var reader = new FileReader(); //创建一个fileReader对象 reader.readAsText(input.files[0]); //读取文本内容 reader.onload = function() { if(reader.result) { //显示文件内容 $("#output").html(reader.result); window.dynamicUpdate(reader.result); //更新文本 fileName = input.files[0].name; //保存文件名 } };
-
协同文本编辑
- 实时监听文本变化
$(document).on("input propertychange",".notifyDetail",function(){ window.dynamicUpdate(document.getElementById('output').value); });
- 注册更新文本的事件
function dynamicUpdate(text){ socket.emit('alter text', text); }
- 广播
io.on('connection',(socket) => { socket.on('alter text', (text) => { //console.log(text); io.emit('update text', text); }); });
- 更新文本
socket.on('update text', function(text){ t.value = text; })
-
保存文件
$('#btn_save').click(function(){ var content = document.getElementById('output').value; //alert(content); //alert(fileName); if(fileName =='null'){ alert('null'); fileName = 'untitled.txt' } let downLink = document.createElement('a') downLink.download = fileName //字符内容转换为blod地址 let blob = new Blob([content]) downLink.href = URL.createObjectURL(blob) // 链接插入到页面 document.body.appendChild(downLink) downLink.click() // 移除下载链接 document.body.removeChild(downLink) });
3.2 使用socket.io搭建server
const app = require('express')();
const http = require('http').createServer(app);
const io = require('socket.io')(http);
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
http.listen(3000, () => {
console.log('listening on *:3000');
});
这段代码作用如下:
1. Express 初始化 app 作为 HTTP 服务器的回调函数
2. 定义了一个路由 / 来处理首页访问
3. 使 http 服务器监听端口 3000
- 3.3 测试
此时在项目目录下运行命令: node index.js
就可看到:
在浏览器中访问 http://localhost:3000
就可看到:
点击 选择文件
选择要编辑的文本:
在本地开启多个客户端(浏览器)观察 :
测试编辑的实时更新:
保存文件,将编辑的文本下载到本地:
查看是否编辑成功:(看到追加在文本后的 --------
)
4. 实验总结
本次实验,通过学习WebSocket,结合socket.io,基于web框架简单实现了协同编辑文档的功能,达到了实时通讯的效果。
但并没有拓展别的功能,如字体设置、格式设置等(像其他在线文档那样的快捷功能)