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;
       		 } 
           } 

分享完毕,有兴趣可以关注我。
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值