layim的websocket消息撤回功能实现

Wesley13
• 阅读 639

我的大概思路就是,前端根据选取的内容获得他的cid,我的cid是js生成的uuid,
然后:1、通过websocket广播给对应的人 去删除localstorage里的缓存,
2、ajax异步请求删除数据库里的数据记录
3、如果对方此时也打开了聊天面板就要用jquery找到那条消息然后remove。

由于目前发现layim3.6版本并没有给自己发的消息赋值data-cid,所以实现起来比较麻烦。
首先如果你的layim和我一样嵌入到很多页面使用的话,你需要找到一个公共的head.jsp或者menu.jsp去存放uuid的值。如下

<input type="hidden" value="" id="uuid">

然后修改layim.js源码如下
在末尾加入一个生成uuid的函数

  , guid=function() {
        var s = [];
        var hexDigits = "0123456789abcdef";
        for (var i = 0; i < 36; i++) {
            s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
        }
        s[14] = "4";  // bits 12-15 of the time_hi_and_version field to 0010
        s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);  // bits 6-7 of the clock_seq_hi_and_reserved to 01
        s[8] = s[13] = s[18] = s[23] = "-";
        var uuid = s.join("");
        return uuid;
    }
  ;

修改发送消息的部分代码如下

  //发送消息
  var sendMessage = function(){
    var uuid=guid();
    $("#uuid").val(uuid);
    var data = {
      username: cache.mine ? cache.mine.username : '访客'
      ,avatar: cache.mine ? cache.mine.avatar : (layui.cache.dir+'css/pc/layim/skin/logo.jpg')
      ,id: cache.mine ? cache.mine.id : null
      ,cid: $("#uuid").val()
      ,mine: true
    };

实现撤回消息的核心代码如下

$("body").on("mousedown",".layim-chat-mine>.layim-chat-text",function(e){
        if(e.which == 3){
            var cid =$(e.target).parent().data("cid")==undefined?$(e.target).parent().parent().data("cid"):$(e.target).parent().data("cid");
            var msgDom=$(".layim-chat-mine[data-cid='"+cid+"']")
            var time= msgDom.find("i").html();  //消息发布时间字符串
            var now=new Date();   //当前时间
            var msgTime = new Date(Date.parse(time.replace(/-/g,"/")));      //消息发布时间转换成Date格式
            console.log(now+"---"+msgTime);
            if((now - msgTime)/60000 < 2){    //只能撤回2分钟内的消息
                layer.confirm('确定要撤回消息吗?', {icon: 3, title:'提示'}, function(index){
                    //console.log(cid);
                    // var windowName=msgDom.find(".layim-chat-other>img").attr("class");
                    var windowName =$(e.target).parent().parent().parent().find(".layim-chat-other>img").attr("class")==undefined?$(e.target).parent().parent().parent().parent().find(".layim-chat-other>img").attr("class"):$(e.target).parent().parent().parent().find(".layim-chat-other>img").attr("class");
                    //console.log(windowName);
                    var arr=windowName.split(" ");
                    var localIndex = arr[0].substring(6,windowName.length);  
                    //console.log(localIndex);
                    var cache =  layui.layim.cache();
                    var local = layui.data('layim')[cache.mine.id];     //获取当前用户本地数据
                    //console.log(JSON.stringify(local));
                    var s=local.chatlog[localIndex];
                    //console.log(JSON.stringify(s));
                    var type=s[0].type;
                    var toId=s[0].id;
                    $.post("api/friend/delMsgFromMongoByCid",{"cid":cid,"type":type},function(res){
                        console.log(res);
                    })
                    console.log(type);
                    var array=[];
                    $.each(s,function(k,v){
                        if(v.cid!=cid){
                            array.push(v);
                        }
                    });
                    local.chatlog[localIndex]=array;
                    //向localStorage同步数据
                    layui.data('layim', {
                      key: cache.mine.id
                      ,value: local
                    });
                    //console.log(local.chatlog[localIndex])
                if(type=='friend'){
                        var obj={
                               "mine":{
                                   "id":userId        
                                 },   
                                 "to":{
                                   "type":"delMsg", 
                                   "cid":cid,
                                   "id":toId,
                                   "toType":type
                                 }
                               };
                        ws.send(JSON.stringify(obj));
                 }else{
                       $.post("api/qun/getSimpleMemberByGroupId?groupId="+toId,function(res){
                           console.log(res);
                            if(res!=null){
                               var obj1={
                                       "mine":{
                                           "id":userId        
                                         },   
                                         "to":{
                                           "type":"delMsg", 
                                           "cid":cid,
                                           "id":toId,
                                           "toType":type,
                                           "memberList":res
                                         }
                               }
                              ws.send(JSON.stringify(obj1));    //发送消息倒Socket服务
                            }
                       })
                 }
                    $(e.target).parent().remove(); 
                    layer.close(index);
                });
            }else{
                layer.msg("超过2分钟的消息无法撤回!",{time:1000});
            }
        }
    });

禁用浏览器默认右键菜单

document.oncontextmenu=function(ev){
    return false;    //屏蔽右键菜单
}

接收撤销的websocket消息的代码如下

   ws.onmessage = function (event) {    //如果获取到消息,心跳检测重置
        heartCheck.reset().start();      //拿到任何消息都说明当前连接是正常的
        console.log("llws收到消息啦:" +event.data);
        if(event.data!='pong'){
            var obj=eval("("+event.data+")");
            layui.use(['layim'], function(layim){
                if(obj.type=="onlineStatus"){
                    layim.setFriendStatus(obj.id, obj.content);
                }else if(obj.type=="friend" || obj.type=="group"){
                    layim.getMessage(obj);  
                }else if(obj.type=="delMsg"){
                    var cid =obj.cid;
                    var type=obj.toType;
                    var toId=obj.toId;
                    var uId=obj.userId;
                    //console.log(cid);
                    $(".layim-chat-main li[data-cid='"+cid+"']").remove();
                    var cache =  layui.layim.cache();
                    var local = layui.data('layim')[cache.mine.id];     //获取当前用户本地数据
                    //console.log(JSON.stringify(local));
                    var localIndex="";
                    if(type=='friend'){
                        localIndex=type+uId;    
                    }else{
                        localIndex=type+toId;
                    }
                    //console.log(localIndex);
                    var s=local.chatlog[localIndex];
                    //console.log(JSON.stringify(s));
                    var array=[];
                    $.each(s,function(k,v){
                        if(v.cid!=cid){
                            array.push(v);
                        }
                    });
                    local.chatlog[localIndex]=array;
                    //向localStorage同步数据
                    layui.data('layim', {
                      key: cache.mine.id
                      ,value: local
                    }); 

                }
            });
        }
    };

java服务端代码如下

if(type.equals("delMsg")){
               String toType=jsonObject.getJSONObject("to").getString("toType");
               String toId=jsonObject.getJSONObject("to").getString("id");
               String cid=jsonObject.getJSONObject("to").getString("cid");
               String userId=jsonObject.getJSONObject("mine").getString("id");
               JSONObject toMessage=new JSONObject();
               toMessage.put("cid",cid); 
               toMessage.put("userId",userId); 
               toMessage.put("toType",toType);
               toMessage.put("toId",toId);
               toMessage.put("type","delMsg");
               if(toType!=null && toId!=null && cid!=null){
                   switch (toType) {
                    case "friend":                                       //单聊撤回
                          if(mapUS.containsKey(toId+"")){               //如果在线,及时推送撤回消息
                             mapUS.get(toId+"").getAsyncRemote().sendText(toMessage.toString()); //发送消息给对方
                             System.out.println("撤回单聊-来自客户端的消息:" + toMessage.toString()); 
                          }/*else{ //如果不在线 就直接把redis里的那条记录干掉 // 如果是离线用户,删除保存到redis的数据 List<Object> redisLogList = RedisUtils.getObjList(toId+"_msg"); for (int i=0;i<redisLogList.size();i++){ Object o = redisLogList.get(i); String s = o.toString(); if (s.indexOf(cid) > -1){ RedisUtils.removeOneOfList(toId+"_msg", o); break; } } }*/
                        break;
                    case "fankui":                                          //家长与老师反馈消息撤回
                          if(mapUS.containsKey(toId+"")){                  //如果在线,及时推送撤回消息
                              mapUS.get(toId+"").getAsyncRemote().sendText(toMessage.toString()); //发送消息给对方
                              System.out.println("撤回反馈-来自客户端的消息:" + toMessage.toString()); 
                          }/*else{ // 如果是离线用户,删除保存到redis的数据 List<Object> redisLogList = RedisUtils.getObjList(toId+"_msg"); for (Object o : redisLogList){ String s = o.toString(); if (s.indexOf(cid) > -1){ RedisUtils.removeOneOfList(toId+"_msg", o); break; } } }*/
                        break;
                    case "group":
                            //JSONArray memberList=JSONArray.fromObject(llClient.getGroupUser(Integer.parseInt(toId))); //获取群成员userId列表
                            JSONArray memberList=jsonObject.getJSONObject("to").getJSONArray("memberList");
                            if(memberList.size()>0){              
                                for(int i=0;i<memberList.size();i++){ //发送到在线用户(除了发送者)
                                    if(mapUS.containsKey(memberList.get(i)) && !memberList.get(i).equals(jsonObject.getJSONObject("mine").getInt("id")+"")){
                                      session=mapUS.get(memberList.get(i));
                                      session.getAsyncRemote().sendText(toMessage.toString());
                                      System.out.println("撤回群聊-来自客户端的消息:" + toMessage.toString()); 
                                    }/*else if(memberList.get(i).equals(jsonObject.getJSONObject("mine").getInt("id")+"")){ //如果是发送者自己,不做任何操作。 }else{ //如果是离线用户,数据存到redis待用户上线后推送。 List<Object> redisLogList = RedisUtils.getObjList(memberList.get(i) + "_msg"); for (Object o : redisLogList){ String s = o.toString(); if (s.indexOf(cid) > -1){ RedisUtils.removeOneOfList(memberList.get(i) + "_msg", o); break; } } }*/
                                }
                            }
                        break;
                    default:
                        break;
             } 
           } 

分享完毕,有问题可以联系qq:1434262447,加我时备注一下

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这