问题总结:
一、单用户重复登录设备
将每次输入的用户名与已经记录在后台的数组ar比较,如果存在则表示重复。
// 生成数组 var ar=""; socket.on('array', function (val) { ar = val; // console.log(ar); });
if(ar.indexOf(lo.value)==-1){ sweetAlert("恭喜您,登录成功!"); socket.emit('setName', lo.value.trim()); names1(lo.value.trim()); login1.style.display="none"; document.querySelector(".bg").style.display = "none"; document.querySelector(".cd span").style.display = "none"; document.querySelector(".title img").style.display = "block"; document.querySelector(".fix").style.display = "block" ; document.querySelector(".title").style.display = "block" ; document.querySelector(".tit").innerText=lo.value.trim(); document.querySelector(".swal-button").onclick = function () { document.getElementById("text").focus(); document.querySelector(".fix").addEventListener('click', function (e) { if (e.target.nodeName === "LI"&&e.target.innerText != document.querySelector(".tit").innerText) { document.querySelector(".fix").style.display="none"; document.querySelector(".chat_b").style.display="block"; document.querySelector(".box").style.display="block"; document.querySelector(".tit").innerText = e.target.innerText; document.querySelector("#text").focus(); onOff=true; } else{ sweetAlert("不能跟自己聊天哦~"); } }) } } else{ sweetAlert("不能重复登录哦!"); return }
二、不能跟自己聊天
判断点击是否是同一个信息
if (e.target.nodeName === "LI"&&e.target.innerText != document.querySelector(".tit").innerText) { document.querySelector(".fix").style.display="none"; document.querySelector(".chat_b").style.display="block"; document.querySelector(".box").style.display="block"; document.querySelector(".tit").innerText = e.target.innerText; document.querySelector("#text").focus(); onOff=true; } else{ sweetAlert("不能跟自己聊天哦~"); }
三、不使用ajax,不使用数据库,怎么传值,怎么保存信息
可以使用socket.emit()发送到后台, 然后socket.on()监听。
// 传名 function names(value) { this.name=value; socket.emit("reg", name); } function names1(value) { this.name1 = value; socket.emit("join", name1); document.title = name1 + "的臻美Chat" } // 传密码 function pass(value){ socket.emit("pass", value); } socket.on("join", function (user) { this.na = user; }) socket.on("reg", function (user) { this.na1 = user; }) socket.on("pass", function (val) { // console.log(val); }) // 监听后台名 var users2 = ""; socket.on('users', function (users) { users2 = users; // console.log(users2); }); // 监听后台密码 var pass2="" socket.on('pass', function (val) { pass2 = val; // console.log(pass2) });
前台传进来的数据通过写入文件的方式保存。
//名字 socket.on("reg", function (name) { usocket[name] = socket; this.i1=name; io.emit("reg", name); var myname =this.i1+"\n"; fs.writeFile('./user.xls', myname, { 'flag': 'a' }, function (err) { if (err) { throw err; } // 写入成功后读取测试 fs.readFile('./user.xls', 'utf-8', function (err,data) { if (err) { throw err; } }); }); }) // 密码 socket.on("pass",function(val){ pass[val]=socket; this.i2=val; io.emit("pass", val); var password=this.i2+"\n"; fs.writeFile('./password.xls', password, { 'flag': 'a' }, function (err) { if (err) { throw err; } }); })
四、怎么实现私发消息
给每个用户提供生成私有socket
// 获取在线 function broadcast() { io.sockets.emit("dataval", hashName); } //提供私有socket function privateSocket(toId) { return (_.findWhere(io.sockets.sockets, { id: toId })); } // 封装删除 function removeByValue(arr, val) { for (var i = 0; i < arr.length; i++) { if (arr[i] == val) { arr.splice(i, 1); break; } } } // 连接socket var io=ws(server); io.on("connection",function(socket){ // 写入成功后读取测试 fs.readFile('./user.xls', 'utf-8', function (err, data) { if(data!=null){ var value = data.split('\n'); io.sockets.emit("users", value); } }); // 写入成功后读取测试 fs.readFile('./password.xls', 'utf-8', function (err,data) { if(data!=null){ var pass1=data.split('\n'); io.sockets.emit("pass", pass1); } }); broadcast(); // 生成名字 socket.on('setName', function (data) { var name = data; hashName[name] = socket.id; // console.log(hashName[name]); broadcast(); }); // 私聊发送 socket.on('sayTo', function (data) { var toName = data.to; var toId; console.log(toName); if (toId = hashName[toName]) { privateSocket(toId).emit('message1', data); } });
五、当两个以上用户同时登录出现用户列表被清空,实现实时更新列表
使用数组去重,每次捕捉在线的用户,重新赋值
// 统计在线人数 var arrh=[] socket.on('dataval', function (val) { vf = val; console.log(vf); for (let i = 0; i < vf.length; i++) { // uu++ arrh.push(vf[i]) console.log(arrh) } var rf = [...new Set(arrh)] console.log(rf) rf=vf for (let j = 0; j < rf.length; j++) { var li = document.createElement("li"); li.classList.add("active"); li.innerText = rf[j] console.log(rf[j]) socket.emit("time", rf[j]); document.querySelector(".fix").appendChild(li); } }); socket.on('join', function (val) { document.querySelector(".fix").innerHTML = '' }) socket.on('disconnect', function (val) { document.querySelector(".fix").innerHTML = '' })
六、离线发送消息
手机端切换后台有效,熄屏无效。
function sock () { return io.connect("localhost:3003"); } // 心跳机制 document.addEventListener('visibilitychange',function() { if(document.visibilityState == 'hidden') { //记录页面隐藏时间 var hiddenTime = new Date().getTime() setTimeout(function(){ io.connect("localhost:3003"); },1500); } else { var visibleTime = new Date().getTime(); //页面再次可见的时间-隐藏时间>3S,重连 if((visibleTime - hiddenTime) / 1000 > 3){ // 主动关闭连接 // console.log('我要断开') io.disconnect() // 1.5S后重连 因为断开需要时间,防止连接早已关闭了 setTimeout(function(){ io.connect("localhost:3003"); },1500); }else{ console.log('还没有到断开的时间') } } }) var socket = sock()