diff --git a/io/io.js b/io/io.js index 8361b48..5b81268 100644 --- a/io/io.js +++ b/io/io.js @@ -33,30 +33,29 @@ function ioServer(io) { } }; - io.on('connection', function (socket) { - console.log('SocketIO有新的连接!'); - - _self.updateOnlieCount(true); + io.on('connection',async function (socket) { + console.log('有新的连接进来了:', socket.id); //用户与Socket进行绑定 socket.on('login', async function (msg) { var uid = msg.uid; + socket._user = msg; let type = msg.type; // 获取用户类型 - console.log(uid + '登录成功'); + console.log(type, uid, '登录成功'); //如果不是客服登录 if (type != 'kefu') { let gongHao = msg.gongHao; console.log('new customer login process gongHao=>', gongHao) // 获取管理员的socket - try{ + try { //获取管理员 socket - let kefuData =await sessoionModel.find(gongHao); - if(kefuData){ // 找到客服数据 + let kefuData = await sessoionModel.find(gongHao); + if (kefuData) { // 找到客服数据 let location = Common.getIpLocation(msg.ip); - let socket = socket.id; - let type = 'customer'; - let kefu_id = gongHao; + // let socket = socket.id; + // let type = 'customer'; + // let kefu_id = gongHao; let clientInfo = { "uid": uid, @@ -64,105 +63,63 @@ function ioServer(io) { "type": 'online' }; // 添加客户到 对应的客服 - sessoionModel.create({ + await sessoionModel.createOrUpdate({uid}, { uid, - socket:socket.id, - type:'customer', - kefu_id:gongHao, - nickname:clientInfo.name, + socket: socket.id, + type: 'customer', + kefu_id: gongHao, + nickname: clientInfo.name, }) // 给管理员发送通知 - io.to(kefuData.socket).emit('update-users', info); + io.to(kefuData.socket).emit('update-users', clientInfo); } - }catch (e) { + } catch (e) { //TODO 失败重发机制 - console.log('给管理员发送通知失败'); + console.log('给管理员发送通知失败',e); } } - - //将用户id和socket进行保定 - // redis.set(uid, socket.id, 3600 * 3, function (err, ret) { - // if (err) { - // console.error(err); - // } - // }); - - // redis.set(socket.id,uid,null,function (err,ret) { - // if(err){ - // console.error(err); - // } - // }); - + else { + try { + // 保存客服socket + sessoionModel.createOrUpdate({uid}, { + uid, + socket: socket.id, + type: 'kefu', + nickname: '客服 ' + uid, + status: 1 + }) + } catch (e) { + console.log('客服' + uid + '登录失败了', e); + } + } }); //断开事件 - socket.on('disconnect', function () { + socket.on('disconnect', async function () { console.log("与服务其断开"); - _self.updateOnlineCount(false); + // _self.updateOnlineCount(false); + let user = socket['_user']; + if (user) { + // 更新用户状态 + await sessoionModel.update(user.uid, {status: 0}); + if (user.type == 'customer') { + // 查找对应kf通知下线操作 + let kf_data = await sessoionModel.find(user.kefu_id); + if (kf_data && kf_data.status == 1) { // 客服在线才通知哟 - redis.get(socket.id, function (err, val) { - if (err) { - console.error(err); - } - redis.del(socket.id, function (err, ret) { - if (err) { - console.error(err); + var info = { + "uid": user.uid, + "name": '客户下线', + "type": 'offline' + }; + io.to(kf_data.socket).emit('update-users', info); } - - }); - redis.del(val, function (err, ret) { - if (err) { - console.error(err); - } - }); - //通知用户下线 - if (val != AppConfig.KEFUUUID) { - redis.get(AppConfig.KEFUUUID, function (err, sid) { - if (err) { - console.error(err); - } - if (sid) { - var info = { - "uid": val, - "name": '客户下线', - "type": 'offline' - }; - io.to(sid).emit('update-users', info); - } - }); - - redis.get('user-uuids', function (err, uuids) { - if (err) { - console.error(err); - } - if (uuids) { - uuids = JSON.parse(uuids); - } else { - uuids = []; - } - val = parseInt(val); - var idx = __uuids.indexOf(val); - if (idx != -1) { - __uuids.remove(val); - //uuids.splice(idx,1); - var tmp = []; - uuids.forEach(function (user) { - if (user.uid != val) { - tmp.push(user); - } - }); - uuids = JSON.stringify(tmp); - redis.set('user-uuids', uuids, null, function (err, ret) { - if (err) { - console.error(err); - } - }); - } - }); } - }); + } + + }); //重连事件 @@ -171,38 +128,36 @@ function ioServer(io) { }); //监听客户端发送的信息,实现消息转发到各个其他客户端 - socket.on('message', function (msg) { - //保存到数据库 + socket.on('message', async function (msg) { + let userData = socket['_user']; + if (!userData) { + return; + } + //保存消息到数据库 msgModel.add(msg.from_uid, msg.uid, msg.content, msg.chat_type, msg.image, function (err) { if (err) { console.error(err); } }); - if (msg.type == msgType.messageType.public) { - var mg = { - "uid": msg.from_uid, - "content": msg.content, - "chat_type": msg.chat_type ? msg.chat_type : 'text', - "image": msg.image - }; - socket.broadcast.emit("message", mg); + const sendMsg = { + "uid": msg.from_uid, + "content": msg.content, + "chat_type": msg.chat_type ? msg.chat_type : 'text', + "image": msg.image + }; + if (msg.type == msgType.messageType.public) { // 广播 + socket.broadcast.emit("message", sendMsg); } else if (msg.type == msgType.messageType.private) { - var uid = msg.uid; - redis.get(uid, function (err, sid) { - if (err) { - console.error(err); - } - if (sid) { - //给指定的客户端发送消息 - var mg = { - "uid": msg.from_uid, - "content": msg.content, - "chat_type": msg.chat_type ? msg.chat_type : 'text', - "image": msg.image - }; - io.to(sid).emit('message', mg); + let uid = msg.uid; // 对方uid + // 暂时不 await + sessoionModel.find(uid).then(toUser => { + if (toUser && toUser.status == 1) { // 对方在线才发送消息哟 + io.to(toUser.socket()).emit('message', sendMsg); } + }).catch(e => { + }); + } }); diff --git a/model/session.js b/model/session.js index 35994d0..a72a96b 100644 --- a/model/session.js +++ b/model/session.js @@ -6,11 +6,11 @@ var Schema = mongoose.Schema; // session模型 var SessionSchema = new Schema({ uid: {type: String, index: true}, - socket: {type: String}, + socket: {type: String,index:true}, // 类型 type: {type: String, default: "customer"}, // 客服编号 - kefu_id: {type: String}, + kefu_id: {type: String,default:""}, nickname: {type: String}, status: {type: Number,default:1}, create_at: {type: Date, default: Date.now} @@ -29,9 +29,34 @@ module.exports = { }) }); }, + createOrUpdate(condition,data){ + return new Promise((success, fail) => { + sessionModel.findOne(condition, (err, session) => { + if(err){ + fail(err);return; + } + try{ + if(session){ + sessionModel.update(condition,data, (err, doc) => { + if (err) fail(err); + else success(doc); + }) + }else{//新增 + let model = new sessionModel(data); + model.save(data, (err, doc) => { + if (err) fail(err); + else success(doc); + }) + } + }catch (e) { + fail(e) + } + }); + }); + }, create(data) { return new Promise((success, fail) => { - sessionModel.insert(data, (err, doc) => { + sessionModel.save(data, (err, doc) => { if (err) fail(err); else success(doc); }) diff --git a/public/js/client/client.js b/public/js/client/client.js index 750546c..d9edf34 100644 --- a/public/js/client/client.js +++ b/public/js/client/client.js @@ -93,7 +93,7 @@ $(function(){ } - const gongHao = 10002; + const gongHao = 10001; $("#btnSend").click(function(){ var msg = $("#textarea").val(); if(msg){ @@ -192,8 +192,12 @@ $(function(){ //连接服务器 socket.on('connect', function () { //uuid = 'chat'+ guid(); - var fp1 = new Fingerprint(); - uuid = fp1.get(); + let uuid_store_key = 'kf_c_uuid'; + uuid = localStorage.getItem(uuid_store_key); + if(!uuid){ + uuid = (new Fingerprint()).get(); + localStorage.setItem(uuid_store_key,uuid);//save uuid to ls + } console.log('连接成功...'+uuid); var ip = $("#keleyivisitorip").text(); @@ -216,6 +220,9 @@ $(function(){ insert_agent_html(msg); scrollToBottom(); }); + socket.on('log',function (msg) { + console.log(msg); + }) }); \ No newline at end of file diff --git a/public/js/server/index.js b/public/js/server/index.js index a4643ef..57d081d 100644 --- a/public/js/server/index.js +++ b/public/js/server/index.js @@ -242,10 +242,10 @@ layui.use(['layer', 'form', 'jquery'], function () { //连接服务器 socket.on('connect', function () { console.log('连接成功...'); - uuid = 'chat-admin-' + data.username; - var ip = $("#keleyivisitorip").html(); + uuid = data.username; + var ip = $("#keleyivisitorip").text().trim(); var msg = { - "uid": uuid, + "uid": data.username, "ip": ip, type:'kefu' };