kefu/io/io.js

250 lines
8.6 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
*介绍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;