// 客服的id var kf_id = 0; var kf_name = ''; // 是否点击显示表情的标志 var flag = 1; // 发送锁 标识 var sendLock = 0; // 窗口大小标识 var size = 1; // 是否显示默认的聊天记录 var commChat = 1; var wsUrl = 'ws://' + config.socket; //websocket实例 var ws; //避免重复连接 var lockReconnect = false; // 创建一个Socket实例 function createWebSocket(url){ try { ws = new WebSocket(url); // 加锁 lockTextarea(); // showSystem({content: '连接中...'}); document.getElementById('title').innerText = '连接中...'; eventHandle(); } catch (e) { reconnect(url); } } function eventHandle(){ ws.onclose = function () { reconnect(wsUrl); }; ws.onerror = function () { showSystem({content: '连接失败,正在重新连接...'}); document.getElementById('title').innerText = '连接失败,重连中...'; reconnect(wsUrl); }; ws.onopen = function () { // 登录 var login_data = '{"path":"api\/userInit","param":{"type":"user","group" : "' + config.group + '","group_id":"2"},"access_token" : "123456"}'; ws.send(login_data); // 解锁 unlockTextarea(); //心跳检测重置 heartCheck.reset().start(); }; ws.onmessage = function (res) { var data = eval("("+res.data+")"); if (data['type'] != 'ping') { console.log("监听消息"); console.log(data); } switch(data['message_type']){ // 服务端ping客户端 case 'ping': ws.send('{"path":"ping"}'); break; // 已经被分配了客服 case 'connect': kf_id = data.data.kf_id; kf_name = data.data.kf_name; kf_avatar = data.data.kf_avatar; // var input_name = prompt("请输入用户名:"); console.log(kf_name); showSystem({content: '客服 ' + data.data.kf_name + ' 为您服务'}); document.getElementById('title').innerHTML = '与 ' + kf_name + ' 交流中'; if(1 == commChat){ showChatLog(); } unlockTextarea(); break; // 排队等待 case 'wait': lockTextarea(); document.getElementById('title').innerHTML = '请稍后再来'; showSystem(data.data); break; // 监测聊天数据 case 'chat': showMsg(data.data); break; // 问候语 case 'helloMessage': showMsg(data.data, 1); break; // 转接 case 'relinkMessage': commChat = 2; document.getElementById('title').innerHTML = '正在转接中...'; break; // 提示信息 case 'alert': layer.msg(data.data); break; } //如果获取到消息,心跳检测重置. 拿到任何消息都说明当前连接是正常的 heartCheck.reset().start(); } } function reconnect(url) { if(lockReconnect) return; lockReconnect = true; //没连接上会一直重连,设置延迟避免请求过多 setTimeout(function () { createWebSocket(url); lockReconnect = false; }, 2000); } //心跳检测 var heartCheck = { timeout: 30000,//10秒 timeoutObj: null, serverTimeoutObj: null, reset: function(){ clearTimeout(this.timeoutObj); clearTimeout(this.serverTimeoutObj); return this; }, start: function(){ var self = this; this.timeoutObj = setTimeout(function(){ //这里发送一个心跳,后端收到后,返回一个心跳消息, //onmessage拿到返回的心跳就说明连接正常 ws.send(JSON.stringify({ path: 'ping', param: {'type':'user'} })); self.serverTimeoutObj = setTimeout(function(){//如果超过一定时间还没重置,说明后端主动断开了 ws.close();//如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次 }, self.timeout); }, this.timeout); } }; if(config != undefined && config.socket != undefined){ createWebSocket(wsUrl); } // 点击表情 document.getElementById('up-face').onclick = function(e){ e.stopPropagation(); if(1 == flag){ showFaces(); document.getElementById('face-box').style.display = 'block'; flag = 2; }else{ document.getElementById('face-box').style.display = 'none'; flag = 1; } }; // 监听点击旁边关闭表情 document.addEventListener("click",function(){ if(2 == flag){ document.getElementById('face-box').style.display = 'none'; flag = 1; } }); // 点击发送消息 document.getElementById('send').onclick = function(){ sendMsg(); document.getElementById('msg').value = ''; // 滚动条自动定位到最底端 wordBottom(); }; document.getElementById('msg').onkeydown = function (event) { if (event.ctrlKey && event.keyCode == 13) { sendMsg(); document.getElementById('msg').value = ''; // 滚动条自动定位到最底端 wordBottom(); } }; // 改变窗体事件 window.onresize = function(){ if(1 == size){ size = 2; document.getElementById('face-box').style.top = '58%'; document.getElementById('chat-content-box').style.height = '75%'; }else if(2 == size){ size = 1; document.getElementById('face-box').style.top = '190px'; document.getElementById('chat-content-box').style.height = '60%'; } }; // 图片 文件上传 layui.use(['upload', 'layer'], function () { var upload = layui.upload; var layer = layui.layer; // 执行实例 var uploadInstImg = upload.render({ elem: '#up-image' // 绑定元素 , accept: 'images' , exts: 'jpg|jpeg|png|gif' , url: '/index/upload/uploadImg' // 上传接口 , done: function (res) { sendMsg('img[' + res.data.src + ']'); showBigPic(); } , error: function () { // 请求异常回调 } }); }); // 获取时间 function getTime(){ var myDate = new Date(); var hour = myDate.getHours(); var minute = myDate.getMinutes(); var second = myDate.getSeconds(); if(hour < 10) hour = '0' + hour; if(minute < 10) minute = '0' + minute; if(second < 10) second = '0' + second; return hour + ':' + minute + ':' + second; } // 展示系统消息 function showSystem(msg){ var _html = document.getElementById('chat-list').innerHTML; _html += ''; document.getElementById('chat-list').innerHTML = _html; } // 发送信息 function sendMsg(sendMsg){ console.log("客户端发送消息了"); if(1 == sendLock){ return false; } var msg = (typeof(sendMsg) == 'undefined') ? document.getElementById('msg').value : sendMsg; if('' == msg){ return false; } var _html = document.getElementById('chat-list').innerHTML; var time = getTime(); var content = replaceContent(msg); _html += '
' + '
' + '
' + time + '
' + '
' + content + '
' + '
' + '
' + '
' + '
'; // 发送消息 ws.send(JSON.stringify({ path: 'api\/chat', param: {type:'user',to_id: kf_id, to_name: kf_name, content: msg, from_name: config.name, from_id: JSON.parse(config.token).user.user_id, from_avatar: config.avatar}, access_token: JSON.parse(config.token) })); // 储存我发出的信息 var key = kf_id + '-' + JSON.parse(config.token).user.user_id; if(typeof(Storage) !== "undefined"){ var localMsg = getCache(key); if(localMsg == null || localMsg.length == 0){ localMsg = []; } localMsg.push({type: 'mine', name: '我', avatar: config.avatar, time: time, content: content}); cacheChat({key: key, data: localMsg}); } document.getElementById('chat-list').innerHTML = _html; // 滚动条自动定位到最底端 wordBottom(); showBigPic(); } // 展示发送来的消息 function showMsg(info, flag){ console.log("展示发送来的消息"); //发送消息提醒 sendWarnAudio('msg'); // 清除系统消息 document.getElementsByClassName('mylink-chat-system').innerHTML = ''; var _html = document.getElementById('chat-list').innerHTML; var content = replaceContent(info.content); _html += '
' + '
' + '' + '
' + '
' + '
' + info.name + ' ' + '' + info.time + '' + '
' + '
' + content + '
' + '
' + '
'; document.getElementById('chat-list').innerHTML = _html; showBigPic(); // 滚动条自动定位到最底端 wordBottom(); // 储存我收到的信息 var key = kf_id + '-' + JSON.parse(config.token).user.user_id; if(typeof(Storage) !== "undefined" && typeof(flag) == "undefined"){ var localMsg = getCache(key); if(localMsg == null || localMsg.length == 0){ localMsg = []; } localMsg.push({type: 'other', name: info.name, avatar: info.avatar, time: info.time, content: content}); cacheChat({key: key, data: localMsg}); } } // 展示表情数据 function showFaces(){ var alt = getFacesIcon(); var _html = ''; document.getElementById('face-box').innerHTML = _html; } // 选择表情 function checkFace(obj){ var msg = document.getElementById('msg').value; document.getElementById('msg').value = msg + ' face' + obj.title + ' '; document.getElementById('msg').focus(); document.getElementById('face-box').style.display = 'none'; flag = 1; } // 缓存聊天数据 [本地存储策略] function cacheChat(obj){ if(typeof(Storage) !== "undefined"){ localStorage.setItem(obj.key, JSON.stringify(obj.data)); } } // 从本地缓存中,拿出数据 function getCache(key){ return JSON.parse(localStorage.getItem(key)); } // 展示本地聊天缓存 function showChatLog(){ var chatLog = getCache(kf_id + '-' + JSON.parse(config.token).user.user_id); if(chatLog == null || chatLog.length == 0){ return ; } var _html = ''; var len = chatLog.length; for(var i = 0; i < len; i++){ var item = chatLog[i]; if('mine' == item.type){ _html += '
' + '
' + '
' + item.name + ' ' + '' + item.time + '' + '
' + '
' + item.content + '
' + '
' + '
' + '' + '
' + '
'; } else if('other' == item.type){ _html += '
' + '
' + '' + '
' + '
' + '
' + item.name + ' ' + '' + item.time + '' + '
' + '
' + item.content + '
' + '
' + '
'; } } document.getElementById('chat-list').innerHTML = _html; showBigPic(); // 滚动条自动定位到最底端 wordBottom(); } // 锁住输入框 function lockTextarea(){ sendLock = 1; document.getElementById('msg').setAttribute('readonly', 'readonly'); } // 解锁输入框 function unlockTextarea(){ sendLock = 0; document.getElementById('msg').removeAttribute('readonly'); } // 双击图片 function showBigPic(){ layui.use('jquery', function(){ var $ = layui.jquery; $(".layui-mylink-photos").on('click', function () { var src = this.src; layer.photos({ photos: { data: [{ "alt": "大图模式", "src": src }] } , shade: 0.5 , closeBtn: 2 , anim: 0 , resize: false , success: function (layero, index) { } }); }); }); } // 对话框定位到最底端 function wordBottom(){ var ex = document.getElementById("chat-list"); ex.scrollTop = ex.scrollHeight; } /** * 发送播放声音 * @param type */ function sendWarnAudio(type) { //获取播放器 var turnAudio = document.getElementById("myWarnAudio"); var outTime = 0; if(!turnAudio){ console.log('初始化'); turnAudio = document.createElement("audio"); document.body.appendChild(turnAudio); turnAudio.id = "myWarnAudio"; turnAudio.controls = false; turnAudio.loop = false; turnAudio.hidden = true; outTime = 2000; } //声音类型 if(type == 'msg') { turnAudio.src = "/static/common/mp3/iqq.mp3"; } //播放声音 turnAudio.play(); }