/* *介绍:socket.io 功能封装 *作者:TaiGuangYin *时间:2017-09-09 * */ var redis = require('../utils/redis'); var msgType = require('./messageTpye'); var ioSvc = require('./ioHelper').ioSvc; var AppConfig = require('../config'); var Common = require('../utils/common'); var msgModel = require('../model/message'); const sessoionModel = require('../model/session'); const userModel = require('./../model/users'); //服务端连接 function ioServer(io) { var _self = this; ioSvc.setInstance(io); var __uuids = []; //初始化连接人数 // redis.set('online_count', 0, null, function (err, ret) { // if (err) { // console.error(err); // } // }); Array.prototype.remove = function (val) { var index = this.indexOf(val); if (index > -1) { this.splice(index, 1); } }; 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(type, uid, '登录成功'); //如果不是客服登录 if (type != 'kefu') { let gongHao = msg.kefu_id; let location = Common.getIpLocation(msg.ip); // 获取管理员的socket try { //获取管理员 socket let kefuData = await sessoionModel.find(gongHao,null); if (kefuData) { // 找到客服数据 console.log('来自', location, '的客户连接,处理客服 gongHao=>', gongHao) // let socket = socket.id; // let type = 'customer'; // let kefu_id = gongHao; let clientInfo = { uid, nickname: location + ' 客户', type: 'online', status: 1, }; // 添加客户到 对应的客服 await sessoionModel.createOrUpdate({uid}, (isCreate) => { console.log('is new ',isCreate); let data = { uid, socket: socket.id, kefu_id: gongHao, status: 1 }; if (isCreate) { data['type'] = 'customer'; data['nickname'] = clientInfo.nickname; } return data; }) socket.emit('connect-success',{ nickname:kefuData.nickname, socket:kefuData.socket, status:kefuData.status }); // 给管理员发送通知 io.to(kefuData.socket).emit('update-users', clientInfo); }else{ socket.emit('log','暂无客服可用,请使用其他方式联系!') } } catch (e) { //TODO 失败重发机制 console.log('给管理员发送通知失败', e); } } else { try { let kefu = await userModel.findByUserName(uid); // 保存客服socket sessoionModel.createOrUpdate({uid}, { uid, socket: socket.id, type: 'kefu', nickname: kefu.nickname, status: 1 }) try{ let sessList = await sessoionModel.findByCondition({status:1,kefu_id:uid}); sessList.forEach(s => { io.to(s.socket).emit('connect-success',{ nickname:kefu.nickname, socket:socket.id, status:1 }); // io.to(s.socket).emit('kefu-logout', user); }); }catch(e){ } } catch (e) { console.log('客服 ' + uid + ' 登录失败了', e); } } }); //断开事件 socket.on('disconnect', async function () { // _self.updateOnlineCount(false); let user = socket['_user']; if (user) { // 更新用户状态 await sessoionModel.update(user.uid, {status: 0}); console.log("用户已经中断了连接",user); if(user.type == 'kefu'){ // 将所有的客服服务对象下线 try{ let sessList = await sessoionModel.findByCondition({status:1,kefu_id:user.uid}); sessList.forEach(s => { io.to(s.socket).emit('kefu-logout', user); }); }catch(e){ } return; } if (user.type == 'customer' && user.kefu_id) { // 查找对应kf通知下线操作 let kf_data = await sessoionModel.find(user.kefu_id); if (kf_data && kf_data.status == 1) { // 客服在线才通知哟 let info = { "uid":user.uid, "type": 'offline', "nickname":"", status: 0 }; io.to(kf_data.socket).emit('update-users', info); } } } }); //重连事件 socket.on('reconnect', function () { console.log("重新连接到服务器"); }); //监听客户端发送的信息,实现消息转发到各个其他客户端 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); } }); 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) { let uid = msg.uid; // 对方uid console.log('find kefu data', msg) // 暂时不 await sessoionModel.find(uid).then(toUser => { console.log('find kefu data', toUser) if (toUser && toUser.status == 1) { // 对方在线才发送消息哟 io.to(toUser.socket).emit('message', sendMsg); } }).catch(e => { console.log('find kefu data exception', e) }); } }); }); this.updateOnlineCount = function (isConnect) { return; // 更新在线客户连接数 redis.get('online_count', function (err, val) { if (err) { console.error(err); } if (!val) { val = 0; } if (typeof val == 'string') { val = parseInt(val); } if (isConnect) { val += 1; } else { val -= 1; if (val <= 0) { val = 0; } } console.log('当前在线人数:' + val); io.sockets.emit('update_online_count', {online_count: val}); redis.set('online_count', val, null, function (err, ret) { if (err) { console.error(err); } }); }); }; } //模块导出 exports.ioServer = ioServer;