layim的websocket訊息撤回功能實現
阿新 • • 發佈:2018-10-31
我的大概思路就是,前端根據選取的內容獲得他的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,加我時備註一下