1、协同编辑的意思是什么?

其实,协同编辑无非就是字面意思,多人同时编辑,并且能够同步看到对方问保存的数据,典型的例子可以参考石墨文档,腾讯文档。

2、技术解决

核心技术就是信息的实时通信

以及多人编辑时所产生的冲突

这里我采用websocket来进行实时通信,大家都知道他是一个全双工通信协议,经过时间的考证,还是非常好用的,多数流行语言都有与之响应封装好的软件包

它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。详细的概念可以百度自行查找,比比皆是

编辑冲突的问题可以使用合并算法,上锁等技术(这里没有做过多的研究,所以我使用下面的方式,嘻嘻)

编辑冲突问题交给用户,当前用户实时地看到了别人正在编辑,那么当前用户就自觉性地停止编辑。

3、实现思路

1. 用户打开图像编辑页面,与后端建立长连接。
2. 后端将当前用户加入当前图像编辑列表。
3. 前端监听用户对于图像内容的修改,每一次修改将整个修改内容发送给后端。
4. 后端接收到信息,不做任何处理,直接将图像信息发送给图像编辑用户列表中其他的所有用户。
5. 前端收到后端的文本信息直接覆盖掉当前图像内容。

4、示例

废话就不多说了,直接上代码(复制粘贴即可使用呦)

这里是使用java语言编写的,采用的是原生注解方式,还有其他实现方式,在这里不一一介绍了(主要是上百度搜的没几个能用的,不是相关代码不全,就是长篇大论,最后还是不行,我实在是不会用啊!!!)

首先我们要使用websocket,肯定是要在pom里导入依赖包的(maven无法解析的,可以添加一下响应的版本号)

        <!-- webscoket        --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>

创建MyWebSocketConfig文件来注入bean

package com.example.javawebsocket;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;//@Configuration注解标识的类中声明了1个或者多个@Bean方法,Spring容器可以使用这些方法来注入Bean
@Configuration
public class MyWebSocketConfig {@Beanpublic ServerEndpointExporter serverEndpointExporter() {return new ServerEndpointExporter();}
}

接下来就是创建一个原生注解的文件

package cn.staitech.system.utils;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;import cn.staitech.common.security.utils.SecurityUtils;
import com.alibaba.fastjson.parser.JSONToken;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
@Component
//主要是将目前的类定义成一个websocket服务器端, 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
@ServerEndpoint(value = "/websocket/{imageid}")
//此注解相当于设置访问URL
public class WebSocketServer {/*** 与某个客户端的连接会话,需要通过它来给客户端发送数据*/private Session session;private String userName;/** concurrent包的线程安全Set,用来存放每个客户端对应的CumWebSocket对象。*/private static CopyOnWriteArraySet<WebSocketServer> webSockets =new CopyOnWriteArraySet<>();/**为了保存在线用户信息,在方法中新建一个list存储一下【实际项目依据复杂度,可以存储到数据库或者缓存】**/private static Map<Long,Session> sessionPool = new HashMap<Long,Session>();private static Map<Integer, CopyOnWriteArraySet<WebSocketServer>> newwebSockets = new HashMap<Integer,CopyOnWriteArraySet<WebSocketServer>>();/*** 建立连接* @param session* @param userName*/@OnOpenpublic void onOpen(Session session,@PathParam(value = "imageid") Integer imageid) throws IOException {Long userid = SecurityUtils.getUserId();this.session = session;webSockets.add(this);// 如果id不存在,创建一个新的用户存储池,格式为 图像id:[用户1,用户2]if(! newwebSockets.containsKey(imageid)){CopyOnWriteArraySet<WebSocketServer> webSocketslist =new CopyOnWriteArraySet<>();newwebSockets.put(imageid,webSocketslist);newwebSockets.get(imageid).add(this);}else{newwebSockets.get(imageid).add(this);}sessionPool.put(userid, session);Session res = sessionPool.get(userid);System.out.println(imageid+"【websocket消息】有新的连接,总数为:"+newwebSockets.get(imageid).size());}/*** 断开连接*/@OnClosepublic void onClose(@PathParam(value = "imageid") Integer imageid) {webSockets.remove(this);newwebSockets.get(imageid).remove(this);System.out.println(imageid + "【websocket消息】连接断开,总数为:"+newwebSockets.get(imageid).size());}/*** 发送错误* @param session* @param error*/@OnErrorpublic void onError(Session session, Throwable error) {System.out.println("[连接ID:{}] 错误原因:{}" + this.session + error.getMessage());}/*** 收到信息*/@OnMessagepublic String onMessage(String message) {System.out.println("【websocket消息】收到客户端消息:"+message);return message;}// 此为广播消息public void sendAllMessage(String message,Integer imageid) {for(WebSocketServer webSocket : newwebSockets.get(imageid)) {System.out.println("【websocket消息】广播消息:"+message);try {webSocket.session.getAsyncRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}// 此为单点消息public void sendOneMessage(String userName, String message) {System.out.println("【websocket消息】单点消息:"+message);System.out.println(sessionPool);Session session = sessionPool.get(userName);if (session != null) {try {session.getAsyncRemote().sendText(message);} catch (Exception e) {e.printStackTrace();}}}}

我们我两个接口来调用一下上面两个接口

package com.example.javawebsocket;import com.example.javawebsocket.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;@RestController
@RequestMapping("/annotation")
public class Websocket {@Autowiredprivate WebSocketServer webSocketServer;//    @GetMapping("/sendAllWebSocket")
//    public String test() {
//        String text="你们好!这是websocket群体发送!";
//        webSocketServer.sendAllMessage(text);
//        return text;
//    }@GetMapping("/sendOneWebSocket/{userName}")public String sendOneWebSocket(@PathVariable("userName") String userName) {String text=userName+" 你好! 这是websocket单人发送!";webSocketServer.sendOneMessage(userName,text);return text;}@CrossOrigin@RequestMapping(value = "/newimage",method = RequestMethod.POST)public String newimage(@RequestBody socketvo  req){webSocketServer.sendAllMessage(req.getImagename(), req.getImageid());System.out.println(req.getImagename());return "ok";}}

基本上大致就是酱紫了,可以根据不同需求来自行更改

使用websocket实现协同编辑相关推荐

  1. Springboot2.x+Websocket+js实现实时在线文本协同编辑,并展示协同用户

    文章目录 诉求 相关技术 思路展开 相关步骤 pom配置 服务端相关配置 文本信息.用户广播处理逻辑 前端功能代码 功能测试 小结 诉求 实现页面实时在线文本协同编辑,且显示当前同时编辑文本的用户. ...

  2. Confluence 6 管理协同编辑

    2019独角兽企业重金招聘Python工程师标准>>> 协同编辑能够让项目小组中的协同合作达到下一个高度.这个页面对相关协同编辑中的问题进行了讨论,能够提供给你所有希望了解的内容. ...

  3. Confluence 6 管理协同编辑 - 代理和 SSL 的考虑

    对于你如何连接  Synchrony 是与你的环境有关的.我们知道绝大部分的 Confluence 站点是运行在反向代理后面的,同时还使用了 SSL.这里是帮助你在你环境中识别正确的配置的一些信息和一 ...

  4. Yjs + quill:快速实现支持协同编辑的富文本编辑器

    大家好,我是前端西瓜哥,这次来看看 Yjs 如何帮助我们实现协同编辑能力的. Y.js 是一个支持 协同编辑 的开源库.只要我们将自己的数据转换为 Y.js 提供的 Y.Array.Y.Map 类型, ...

  5. 阻拦协同编辑——时间戳

    只要是团队合作,或是可多人合作操作的产品,就会遇到一个问题--协同编辑的数据变更. 具体情景: 用户A.B 先后打开了同一条数据,并分别进行编辑,且B先于A保存数据,整体流程 如下图: 如果此时,服务 ...

  6. PingCode Wiki 多人实时协同编辑功能发布

    PingCode Wiki 在发布之初,就是希望打造成一个面向组织的知识管理系统. 通过结构化沉淀高价值信息,形成组织完整的知识体系.通过便捷地分享和传播,轻松提升知识的流转效率,更好地成就组织和个人 ...

  7. 手把手玩转协同编辑(1):AST (Address Space Transformation)地址空间转换算法 基本介绍...

    写在前面的话 加入实验室已经有大半年的时间了,科研上一直没有取得什么重大突破.除去自身的实力问题之外,最大的问题恐怕就是对于自己或导师提出的一个问题往往不知道从何入手去研究,如何快速的了解相关工作的现 ...

  8. 文档协同编辑帮助企业迎接大数据时代

    在当今社会,数据暴涨让越来越多的企业在存储和管理数据时,开始关注云存储.而在我国,文档协同编辑是目前发展最迅猛的一种有效的企业网盘存储工具. 比起其他,文档协同编辑在便捷性上表现优异.当企业,特别是正 ...

  9. 多人编辑同一个md_多人协同编辑一份Word文档的正确姿势是这样的

    职场中难免需要:与同事协同编辑一份文档,与领导协同编辑一份文档. 那么如何清晰不混乱地协同编辑呢? 如下图所示,相信不少人在协同编辑文档时都是这样做的,用红字和括号,写明自己想编辑的内容及要修改的点. ...

  10. Confluence 6 管理协同编辑 - 关于 Synchrony

    协同编辑能够让项目小组中的协同合作达到下一个高度.这个页面对相关协同编辑中的问题进行了讨论,能够提供给你所有希望了解的内容. 进入 Collaborative editing 页面来获得项目小组是如何 ...

最新文章

  1. [置顶] 单键模式的C++描述
  2. 01_Difference between case object and object
  3. CSS的clear去除清除浮动元素
  4. 检测机安装mysql_centos安装mysql的正确方法
  5. insert 和 insertSelective的区别
  6. iOS开发之MapKit
  7. 打开模式时防止BODY滚动
  8. 计算机网络物理层之数据通信的基础知识
  9. Mybatis_3.基于注解的增删改查
  10. springboot+poi导出excel
  11. oracle qmon,10g QMON Architecture及AQ_TM_PROCESSES
  12. 设置div背景色为半透明
  13. R语言求一行(列表、list)数据的平均数
  14. 《大话核心网》借鉴一二:科普类文章的写作思路
  15. kafka分布式集群的操作
  16. 百度地图 根据经纬度获取 地址
  17. Mac Mini - 一个深坑
  18. A-Level经济真题每期一练(19)
  19. Android apps 拍立知-功能实现2(相机/选择相册及图像识别调用)
  20. 微信视频压缩画质怎么办?微信发视频怎么不压缩画质

热门文章

  1. 计算机设置u盘启动,如何设置U盘启动_BIOS设置U盘启动教程 - U当家官网
  2. 乐学python靠谱吗_【乐学100】-乐学100怎么样|地址|成立时间-比网校
  3. uniapp微信小程序使用分享功能
  4. 基于JavaScript的Web端股票价格查看器——大道
  5. 彻底解决web调试时,修改css样式后刷新网页无改变
  6. matlab 汽车理论,汽车理论matlab作业
  7. 手机号获取验证码进行登录注册
  8. wps word设置级别多级目录标题
  9. 计算机分盘的时候c盘留多少,win10分区c盘留多大合适
  10. Authentication—身份验证流程