1. 程式人生 > >layim的websocket訊息撤回功能實現

layim的websocket訊息撤回功能實現

我的大概思路就是,前端根據選取的內容獲得他的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,加我時備註一下